用C#XML解析特定内容的XML
我正试图用C#解析来自网站的XML响应。响应的格式类似于以下内容:用C#XML解析特定内容的XML,c#,.net,xml,C#,.net,Xml,我正试图用C#解析来自网站的XML响应。响应的格式类似于以下内容: <Company> <Owner>Bob</Owner> <Contact> <address> -1 Infinite Loop </address> <phone> <LandLine>(000) 555-5555</LandLine>
<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>
我是XML/C#的新手,但上面的方法只会发出糟糕的代码!我希望确保,如果结构发生变化(即,存在诸如“mobile”之类的附加电话号码类型),则代码是健壮的(因此会出现附加的while循环)
注意:上面的C#代码并不精确,并且缺少一些检查等,但它展示了我目前糟糕透顶的方法
如果这两个元素存在,那么从中提取内容的最佳/最干净的方法是什么 下面的文章可能有用
以下文章可能有用 使用:
var doc=XDocument.Parse(@)
上下快速移动
-1无限循环
(000) 555-5555
(000) 555-5556
foo@bar.com
");
var phone=doc.Root.Element(“联系人”).Element(“电话”);
Console.WriteLine((字符串)phone.Element(“固定线路”);
Console.WriteLine((字符串)phone.Element(“Fax”);
输出:
(000) 555-5555
(000) 555-5556
(000) 555-5555
(000) 555-5556
使用:
var doc=XDocument.Parse(@)
上下快速移动
-1无限循环
(000) 555-5555
(000) 555-5556
foo@bar.com
");
var phone=doc.Root.Element(“联系人”).Element(“电话”);
Console.WriteLine((字符串)phone.Element(“固定线路”);
Console.WriteLine((字符串)phone.Element(“Fax”);
输出:
(000) 555-5555
(000) 555-5556
(000) 555-5555
(000) 555-5556
最好的方法是使用XPath。请参阅本文,以供参考:
这篇文章介绍了如何做到这一点:最好的方法是使用XPath。请参阅本文,以供参考:
这篇文章介绍了如何做到这一点:对于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;
}
对于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;
}
我不认为你离得太远。有更方便的方法(许多不同的方法)。假设您希望采用与此处相同的基本方法(这是一种有效的方法,尽管非常详细),我会: 请注意,这将跟踪它是否在“电话”元素中,在该元素中,您所拥有的内容将在稍后的元素中重新检查固定线路,而您似乎正试图避免这样做
还要注意的是,我们清理了XmlReader,并在获得所需的所有信息后立即返回。我不认为您离得太远。有更方便的方法(许多不同的方法)。假设您希望采用与此处相同的基本方法(这是一种有效的方法,尽管非常详细),我会: 请注意,这将跟踪它是否在“电话”元素中,在该元素中,您所拥有的内容将在稍后的元素中重新检查固定线路,而您似乎正试图避免这样做
还请注意,我们会清理XmlReader,并在获得所需的所有信息后立即返回。注意,如果缺少联系人,您将在
var phone=…
行中遇到异常。我喜欢做一些事情,比如var contactNode=doc.Root.Element(“Contact”)??新XElement(“联系人”)代码>所以我总是返回一个节点,然后当我执行var phone=contact.Element(“phone”)时??新XElement(“电话”)代码>我不会得到空对象错误。最后,我得到了变量的空白值。或者在解析之前使用xsd验证文档,以确保您想要的节点存在;通常不是对文档中的节点进行只读随机访问所需的,尤其是在处理大型文档时。请注意,如果缺少联系人,则会在var phone=…
行中出现异常。我喜欢做一些事情,比如var contactNode=doc.Root.Element(“Contact”)??新XElement(“联系人”)代码>所以我总是返回一个节点,然后当我执行var phone=contact.Element(“phone”)时??新XElement(“电话”)代码>我不会得到空对象错误。最后,我得到了变量的空白值。或者在解析之前使用xsd验证文档,以确保您想要的节点存在;通常不是对文档中的节点进行只读随机访问所需的,尤其是在处理大型文档时。这可以工作,但对于只读访问来说并不理想。该示例使用XmlDocument
,它在内存中构建了一个通常不需要的完整DOM树。该示例使用XmlDocument
,它在内存中构建了一个通常不需要的完整DOM树。
bool inPhone = false;
string landLine = null;
string fax = null;
using(xml = XmlReader.Create(websiteResultStream, xmlSettings)
while(xml.Read())
{
switch(xml.NodeType)
{
case XmlNodeType.Element:
switch(xml.LocalName)
{
case "phone":
inPhone = true;
break;
case "LandLine":
if(inPhone)
{
landLine = xml.ReadElementContentAsString();
if(fax != null)
{
DoWhatWeWantToDoWithTheseValues(landline, fax);
return;
}
}
break;
case "Fax":
if(inPhone)
{
fax = xml.ReadElementContentAsString();
if(landLine != null)
{
DoWhatWeWantToDoWithTheseValues(landline, fax);
return;
}
}
break;
}
break;
case XmlNodeType.EndElement:
if(xml.LocalName == "phone")
inPhone = false;
break;
}
}