JavaScript等效于.NET XML反序列化

时间:2014-08-18 12:09:26

标签: javascript unmarshalling xml-deserialization jsonix

我正在寻找能够以类似于.NET XmlSerializer's Deserialize方法的方式将XML(字符串或DOM)反序列化/解组到JavaScript类的JavaScript库。

我正在寻找的功能:

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

  4. 例如,以下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 个答案:

答案 0 :(得分:3)

Alexey Valikov(Jsonixsource)的

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"

JSFiddle上较长的working example使用了来自问题的XML。