处理XML响应并转换为格式不正确的集合

时间:2015-02-18 15:22:49

标签: c# xml

我必须处理来自我无法控制的第三方REST API的XML响应。问题是XML响应的格式不正确,如下所示:

<XML>
<Meta>
<Status>Success</Status>
<Debug/>
</Meta>
<Result>
<abc>
 <DivisionID>tttttttttt</DivisionID>
 <UserName><![CDATA[ xxx#xxxxx]]></UserName>
 <UserFirstName>xxxx</UserFirstName>
 <UserLastName>xxxx</UserLastName>
 <UserAccountType>xxxxxxx</UserAccountType>
 <UserEmail>xxxxx@xxxxx.xom</UserEmail>
 <UserAccountStatus>Active</UserAccountStatus>
</abc>
<def>
 <DivisionID/>
 <UserName><![CDATA[ xxx#xxxx]]></UserName>
 <UserFirstName>yyyy</UserFirstName>
 <UserLastName>vvvvvv</UserLastName>
 <UserAccountType>uuuuuuuuu</UserAccountType>
 <UserEmail>oooo@vvvvvv</UserEmail>
 <UserAccountStatus>Active</UserAccountStatus>
</def>
....contd
</Result>



       var requestUri = new Uri(uriString);
       HttpWebRequest httprequest =  (HttpWebRequest)WebRequest.Create(requestUri);
    var httpresponse = (HttpWebResponse)httprequest.GetResponse();
    Person people = new Person();
    List<Person> lstPerson = (from _person in         xmlDoc.Document.Element("Result").Elements("Result")
      select new Person
      {
      userName = Xdocument.Load(httpresponse.GetResponseStream()).Root.ToString(),
      userEmail = _person.Element("UserEmail").Value
      }).ToList();

我需要检索具有值&#34; abc&#34;的节点。和&#34; def&#34;并将它们存储在UserName中,UserName本身就是根节点,并且还要检索它们之间的值。所以如何做到这一点我尝试了各种各样的方法,但却无法这样做。

1 个答案:

答案 0 :(得分:0)

<强>更新

要使用Person的元素名称和userName的{​​{1}}子元素的值创建UserEmail类的列表,您可以执行以下操作:

userEmail

使用extension method

        try
        {
            // Load the XML from the external site
            XDocument xmlDoc;

            var requestUri = new Uri(uriString);
            HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(requestUri);

            using (var httpresponse = (HttpWebResponse)httprequest.GetResponse())
            using (var stream = httpresponse.GetResponseStream())
            using (var reader = new StreamReader(stream))
            {
                xmlDoc = XDocument.Load(reader);
            }

            // Extract the name & email.
            var people = xmlDoc
                // Get the "Result" node
                .Root.Elements(xmlDoc.Root.Name.Namespace + "Result")
                // Loop through its elements
                .SelectMany(result => result.Elements())
                // Deserialize the element name and UserEmail sub-element value as a Person
                .Select(element => new Person { userName = element.Name.LocalName, userEmail = element.Element(xmlDoc.Root.Name.Namespace + "UserEmail").ValueSafe() })
                .ToList();

            // Process or return the list of people
        }
        catch (Exception ex)
        {
            // Handle any web exception encountered.
            Debug.WriteLine(ex);
            // Or rethrow if it can't be handled here
            throw;
        }

原始答案

你的问题不清楚。但如果你问的话

  

如果我从某些XML加载了public static class XObjectExtensions { public static string ValueSafe(this XElement element) { return element == null ? null : element.Value; } } ,当列表的每个元素都有自定义元素名称时,有没有办法使用XDocument反序列化嵌入列表的部分?

然后你可以这样做:

  1. 加载XmlSerializer
  2. 导航到要反序列化的列表。
  3. 对于每个元素,请记住元素名称,然后使用类名覆盖
  4. 使用XElement.CreateReader()为该元素创建XDocument,然后将其传递给XmlReader进行反序列化。
  5. 即:

    XmlSerializer

    给定XML字符串

        // Load the document
        var doc = XDocument.Parse(xml);
    
        var people = doc
            // Navigate to the list
            .Root.Elements("Result")
            .SelectMany(r => r.Elements())
            // Deserialize each element in the list as a KeyValuePair<string, Person>
            .Select(element =>
                {
                    var name = element.Name;
                    element.Name = typeof(Person).DefaultXmlElementName(); // Overwrite name with name used by serializer.
                    using (var reader = element.CreateReader())
                    {
                        var person = (Person)new XmlSerializer(typeof(Person)).Deserialize(reader);
                        return new KeyValuePair<string, Person>(name.LocalName, person);
                    }
                })
            .ToList();
    

    使用扩展方法:

        string xml = @"<XML>
            <Meta>
                <Status>Success</Status>
                <Debug/>
            </Meta>
            <Result>
                <abc>
                     <DivisionID>tttttttttt</DivisionID>
                     <UserName><![CDATA[ xxx#xxxxx]]></UserName>
                     <UserFirstName>xxxx</UserFirstName>
                     <UserLastName>xxxx</UserLastName>
                     <UserAccountType>xxxxxxx</UserAccountType>
                     <UserEmail>xxxxx@xxxxx.xom</UserEmail>
                     <UserAccountStatus>Active</UserAccountStatus>
                </abc>
                <def>
                     <DivisionID/>
                     <UserName><![CDATA[ xxx#xxxx]]></UserName>
                     <UserFirstName>yyyy</UserFirstName>
                     <UserLastName>vvvvvv</UserLastName>
                     <UserAccountType>uuuuuuuuu</UserAccountType>
                     <UserEmail>oooo@vvvvvv</UserEmail>
                     <UserAccountStatus>Active</UserAccountStatus>
                </def>
            </Result>
        </XML>
        ";