[英]Parsing XML in C# XML for specific Content
我正在尝试从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>
我唯一需要的信息是座机和传真号码。 但是,我当前的方法似乎真的质量很差。 本质上,它是一堆嵌套的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();
}
}
}
}
}
}
我是XML / C#的新手,但是上述方法只会尖叫错误的代码! 我想确保如果结构发生变化(例如,还有其他电话号码类型,例如“手机”),则代码是可靠的(因此,附加的while循环)
注意:上面的C#代码不准确,并且缺少一些检查等,但是它演示了我当前的糟糕透顶方法
从这两个元素中提取内容的最佳/最干净的方法是什么?
使用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"));
输出:
(000) 555-5555 (000) 555-5556
对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;
}
我认为你离得太远了。 有更方便的方法(很多不同的方法)。 假设您希望采用与此处相同的基本方法(如果使用冗长的方法,这是一种有效的方法),我将这样做:
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;
}
}
请注意,这将跟踪它是否在Phone元素内,您将在其中重新检查以后的元素内的LandLine,这似乎是您要避免的。
还要注意,我们清理了XmlReader,并在获得所有所需信息后立即返回。
最好的方法是使用XPath。 请参考本文,以供参考: http : //support.microsoft.com/kb/308333
以及本文的操作方法: http : //www.codeproject.com/KB/cpp/myXPath.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.