C# XML反序列化:包含属性的XML内嵌XML

3

您是否可以更简单地反序列化XML('items'),而不使用'Items'属性内的另一个反序列化来获取数据标记内部的内容。也许在“public Item[] Items”上添加某种属性可以实现。

XML:

<body>
  <request></request>
  <data><![CDATA[    <items>      <item>        <property1>Name1</property1>        <property2>111</property2>      </item>      <item>        <property1>Name2</property1>        <property2>222</property2>      </item>      <item>        <property1>Name3</property1>        <property2>333</property2>      </item>    </items>]]>
  </data>
</body>

测试类:

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            const string xml = "<body>" +
                                    "<request></request>" +
                                    "<data><![CDATA[" +
                                        "<items>" +
                                            "<item>" +
                                                "<property1>Name1</property1>" +
                                                "<property2>111</property2>" +
                                            "</item>" +
                                            "<item>" +
                                                "<property1>Name2</property1>" +
                                                "<property2>222</property2>" +
                                            "</item>" +
                                            "<item>" +
                                                "<property1>Name3</property1>" +
                                                "<property2>333</property2>" +
                                            "</item>" +
                                        "</items>" +
                                    "]]></data>" +
                               "</body>";

            var xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);

            var serializer = new XmlSerializer(typeof (Body));
            var response = serializer.Deserialize(new XmlNodeReader(xmlDoc)) as Body;

            Assert.IsNotNull(response);
            Assert.AreEqual(3, response.Items.Length);
        }
    }

    [Serializable, XmlRoot("body")]
    public class Body
    {
        [XmlElement("request")] 
        public string Request;

        [XmlElement("data")] 
        public string Data;

        public Item[] Items
        {
            get
            {
                var document = new XmlDocument();
                document.LoadXml(Data);

                var serializer = new XmlSerializer(typeof(ItemList));
                var response = serializer.Deserialize(new XmlNodeReader(document)) as ItemList;

                return response.Items;
            }
        }
    }

    [Serializable, XmlRoot("items")]
    public class ItemList
    {
        [XmlElement("item")]
        public Item[] Items;
    }

    [Serializable]
    public class Item
    {
        [XmlElement("property1")]
        public string Property1;

        [XmlElement("property2")]
        public string Property2;
    }

1
你在这种情况下使用 CData 有什么原因吗?为什么不让 Items 正常地进行序列化/反序列化而不需要 Data 属性呢? - Chris Sinclair
3
问题在于CData和Data是字符串,这意味着从技术上讲,Data中的内容是单个字符串,而不是XML,因此您需要进行两个步骤才能对其进行反序列化。 - Chris
好的,谢谢你的解释,我会想办法解决它。 - sulgpallur
1
嗯,好吧,我不知道是否有可以应用的XmlAttribute(尽管我以前可能说错过)。如果我有同样的要求,我会以基本相同的方式处理。虽然我会考虑一些缓存或者在Data setter中写入Items数组,以避免每次访问Items属性时进行反序列化。 - Chris Sinclair
能否将字符串替换为更干净的 XML,例如 xml = xml.Replace("<data><![CDATA[", "<data>").Replace("</items>]]>", "</items>"); - ibram
显示剩余4条评论
1个回答

0

在反序列化 XML 之前,将 XML 加载到 XmlDocument 中,并将 "data" XmlNode 的 InnerXml 更改为以下内容:

if (xmlNode.Contains("<![CDATA[") || xmlNode.InnerXml.Contains("&lt;"))
{
     xmlNode.InnerXml = xmlNode.Value;
}

如果您知道在 CDATA 中将接收什么,这将起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接