代码之家  ›  专栏  ›  技术社区  ›  Samu Lang

与.NET XML反序列化等效的JavaScript

  •  2
  • Samu Lang  · 技术社区  · 10 年前

    我正在寻找一个JavaScript库,它可以以类似于.NET的方式将XML(字符串或DOM)反序列化/反序列化为JavaScript类 XmlSerializer's Deserialize 方法

    我正在寻找的功能:

    1. 类被定义为JavaScript构造函数函数。
    2. 节点和类/财产之间的映射是可配置的。
    3. 反序列化结果由这些类的实例组成。

    例如,以下XML:

    <root textAttribute='text1' numberAttribute='1' attributeToIgnore1='ignored1' attributeToIgnore2='ignored2'>
      <children>
        <child>text2</child>
        <child>text3</child>
      </children>
      <childToIgnore>ignored3</childToIgnore>
    </root>
    

    与以下类似的JavaScript定义一起使用:

    function RootClass() {
      this.stringProperty = "";
      this.integerProperty = 0;
      this.collectionProperty = [];
    }
    
    function ChildClass() {
      this.stringProperty = "";
    }
    

    应生成类似于以下内容的JavaScript对象:

    var result = new RootClass();
    result.textProperty = "text1";
    result.integerProperty = 1;
    result.collectionProperty = [];
    result.collectionProperty[0] = new ChildClass();
    result.collectionProperty[0].textProperty = "text2";
    result.collectionProperty[1] = new ChildClass();
    result.collectionProperty[1].textProperty = "text3;
    

    执行相同操作的.NET(C#)代码示例如下(请参见 this .NET Fiddle for a working example ):

    public class Program
    {
        public static void Main()
        {
            var result = Serializer.Deserialize();
    
            Console.WriteLine("text: {0}", result.StringProperty);
            Console.WriteLine("number: {0}", result.IntegerProperty);
            Console.WriteLine("enum: {0}", result.EnumProperty);
            Console.WriteLine("child[0].Value: {0}", result.CollectionProperty[0].Value);
            Console.WriteLine("other@[0]: {0}", result.OtherAttributes[0].InnerText);
            Console.WriteLine("other*[0]: {0}", result.OtherElements[0].InnerText);
        }
    }
    
    public static class Serializer
    {
        public static RootClass Deserialize()
        {
            var type = typeof (RootClass);
    
            var serializer = new XmlSerializer(type);
    
            var xmlString = @"
                    <root textAttribute='text1' numberAttribute='1' enumAttribute='item1' attributeToIgnore1='ignored1' attributeToIgnore2='ignored2'>
                        <children>
                            <child>text2</child>
                            <child>text3</child>
                        </children>
                        <childToIgnore>ignored3</childToIgnore>
                    </root>";
    
            using (var stringReader = new StringReader(xmlString))
            {
                return serializer.Deserialize(stringReader) as RootClass;
            }
        }
    }
    
    [XmlRoot("root")]
    public class RootClass
    {
        [XmlAttribute("textAttribute")]
        public string StringProperty;
    
        [XmlAttribute("numberAttribute")]
        public int IntegerProperty;
    
        [XmlAttribute("enumAttribute")]
        public Enumeration EnumProperty;
    
        [XmlAnyAttribute]
        public XmlAttribute[] OtherAttributes;
    
        [XmlArray("children")]
        [XmlArrayItem("child")]
        public Collection<ChildClass> CollectionProperty;
    
        [XmlAnyElement]
        public XmlElement[] OtherElements;
    }
    
    public enum Enumeration
    {
        [XmlEnum("item1")]
        Item1,
    
        [XmlEnum("item2")]
        Item2
    }
    
    public class ChildClass
    {
        [XmlText]
        public string Value;
    }
    
    1 回复  |  直到 10 年前
        1
  •  3
  •   Samu Lang    10 年前

    Jsonix 作者Alexey Valikov( source , guide )可以基于可配置映射将XML反序列化为JavaScript。


    我贡献了代码来支持 deserializing custom classes using instance factories 。这将有望成为Jsonix(2.0.11)的下一个版本。


    var input = "<element1 attribute1='value1' />";
    
    var Class1 = function () {};
    Class1.prototype.toString = function () {
        return this.Property1;
    };
    
    var mapping = {
        elementInfos: [{
            elementName: "element1",
            typeInfo: new Jsonix.Model.ClassInfo({
                name: "Element1",
                instanceFactory: Class1,
                propertyInfos: [
                    new Jsonix.Model.AttributePropertyInfo({
                        name: "Property1",
                        attributeName: "attribute1"
                    })
                ]
            })
        }]
    };
    
    var context = new Jsonix.Context([mapping]);
    var unmarshaller = context.createUnmarshaller();
    var result = unmarshaller.unmarshalString(input).value;
    
    console.log(result.toString()); // logs "value1"
    

    更长的时间 working example 在JSFiddle上使用XML。