在C#XML中解析XML以获取特定内容

Toy*_*rii 1 .net c# xml

我试图解析来自C#网站的XML响应.响应的格式类似于以下内容:

<Company>
    <Owner>Bob</Owner>
    <Contact>
        <address> -1 Infinite Loop </address>
        <phone>
            <LandLine>(000) 555-5555</LandLine>
            <Fax> (000) 555-5556 </Fax>
        </phone>
        <email> foo@bar.com </email>
    </Contact>
</Company>
Run Code Online (Sandbox Code Playgroud)

我想要的唯一信息是LandLine和传真号码.然而,我目前的方法似乎真的很差.基本上它是一堆嵌套的while循环并检查Element名称,然后在找到正确的Element时读取Content.我正在使用类似下面的列表:

XmlReader xml = XmlReader.Create(websiteResultStream, xmlSettings);

while(xml.Read()){
    if(xml.NodeType == XmlNodeType.Element){
        if(xml.Name.ToString() == "Phone"){
            while(xml.Read()) {
                if(xml.NodeType == XmlNodeType.Element) {
                     if(xml.Name.ToString() == "LandLine"){
                          xml.MoveToContent();
                          xml.ReadContentAsString();
                     }
                     if(xml.Name.ToString() == "Fax"){
                          xml.MoveToContent();
                          xml.ReadContentAsString();
                     }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我是XML/C#的新手,但上面的方法只是尖叫不好的代码!我想确保如果结构发生变化(即有类似"mobile"的附加电话号码类型),那么代码是健壮的(因此额外的while循环)

注意:上面的C#代码并不准确,并且缺少一些检查等,但它证明了我当前糟糕的恶心方法

如果它们存在的话,从这两个元素中简单地提取内容的最佳/最干净的方法是什么?

dtb*_*dtb 8

使用LINQ-to-XML:

var doc = XDocument.Parse(@"<Company>
    <Owner>Bob</Owner>
    <Contact>
        <address> -1 Infinite Loop </address>
        <phone>
            <LandLine>(000) 555-5555</LandLine>
            <Fax> (000) 555-5556 </Fax>
        </phone>
        <email> foo@bar.com </email>
    </Contact>
</Company>");

var phone = doc.Root.Element("Contact").Element("phone");

Console.WriteLine((string)phone.Element("LandLine"));
Console.WriteLine((string)phone.Element("Fax"));
Run Code Online (Sandbox Code Playgroud)

输出:

(000) 555-5555
 (000) 555-5556

  • 请注意,如果缺少Contact,您将在`var phone = ...`行中获得异常.我喜欢做`var contactNode = doc.Root.Element("Contact")?new XElement("Contact");`所以我总是有一个节点返回,然后当我做`var phone = contact.Element("phone")?? new XElement("phone");`我不会得到null对象错误.最后,我最终得到了变量的空白值.或者在解析之前使用xsd验证文档,以确保您想要的节点存在. (3认同)
  • 请注意,`XDocument`类还带有在内存中构建DOM树的开销; 通常不是您对文档中节点的只读随机访问所需的内容,尤其是在处理大型文档时. (3认同)

Dir*_*mar 8

对XML文档中特定节点进行只读访问的最轻量级方法是XPathDocument与XPath表达式一起使用:

XPathDocument xdoc = new XPathDocument(@"C:\sample\document.xml");
XPathNavigator node = xdoc.CreateNavigator()
    .SelectSingleNode("/Company/Contact/phone/LandLine");
if (node != null)
{
    string landline = node.Value;
}
Run Code Online (Sandbox Code Playgroud)