2013-08-01 2 views
3

Можете ли вы дезертилизовать XML («элементы») внутри другого тега («данные») более простым, не используя другую десерилизацию внутри свойства «Items» get. Может быть, какой-то атрибут на «public Item [] Items».C# XML десериализация XML внутри XML с атрибутами

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:

[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? –

+0

Я получаю этот xml с CData из другой системы – sulgpallur

+3

Проблема в том, что CData и тот факт, что Data является строкой, означает, что технически то, что находится внутри Data, является одной строкой, а не XML, поэтому вы не сможете ее десериализовать без двух шагов. – Chris

ответ

0

Перед десериализации XML, загрузите XML в XmlDocument и изменения "данных" XmlNode InnerXml, как показано ниже:

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

Это будет работать если вы знаете, что вы будете получать внутри CDATA.

Смежные вопросы