我正在尝试解析以下XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soapenv:Body>
<d2LogicalModel modelBaseVersion="1.0" xmlns="http://datex2.eu/schema/1_0/1_0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://datex2.eu/schema/1_0/1_0 http://datex2.eu/schema/1_0/1_0/DATEXIISchema_1_0_1_0.xsd">
<payloadPublication xsi:type="PredefinedLocationsPublication" lang="en">
<predefinedLocationSet id="GUID-NTCC-VariableMessageSignLocations">
<predefinedLocation id="VMS30082775">
<predefinedLocationName>
<value lang="en">VMS M60/9084B</value>
</predefinedLocationName>
</predefinedLocation>
</predefinedLocationSet>
</payloadPublication>
</d2LogicalModel>
</soapenv:Body>
</soapenv:Envelope>
我特别需要获取顶级的predefinedLocation标记的内容。根据我的计算,正确的XPath应该是
/soapenv:Envelope/soapenv:Body/d2LogicalModel/payloadPublication/predefinedLocationSet/predefinedLocation
我使用以下C#代码来解析XML: string filename =“content-sample.xml”;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmlDoc.NameTable);
nsmanager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/Envelope");
string xpath ="/soapenv:Envelope/soapenv:Body/d2LogicalModel/payloadPublication/predefinedLocationSet/predefinedLocation";
XmlNodeList itemNodes = xmlDoc.SelectNodes(xpath, nsmanager);
然而,这一直没有结果。任何人都可以对此有所了解,因为我觉得我正在敲打砖墙。
答案 0 :(得分:2)
d2LogicalModel及其后代不在空命名空间中,而是在“http://datex2.eu/schema/1_0/1_0”命名空间中。您需要将此命名空间添加到命名空间管理器,以便能够选择元素:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmlDoc.NameTable);
nsmanager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/Envelope");
nsmanager.AddNamespace("dataexNs", "http://datex2.eu/schema/1_0/1_0");
string xpath ="/soapenv:Envelope/soapenv:Body/dataexNs:d2LogicalModel/dataexNs:payloadPublication/dataexNs:predefinedLocationSet/dataexNs:predefinedLocation";
XmlNodeList itemNodes = xmlDoc.SelectNodes(xpath, nsmanager);
即使您使用Linq到Xml,也值得使用完全限定名称来选择不具有相同本地名称的内容。
答案 1 :(得分:1)
如果你想避免处理命名空间(使用Linq2Xml)
var xDoc = XDocument.Load(.....);
var loc = xDoc.Root.Descendants2("predefinedLocation").First();
var id = loc.Attribute("id");
var value = loc.Descendants2("value").First().Value;
public static class S_O_Extensions
{
public static IEnumerable<XElement> Descendants2(this XElement xRoot, string name)
{
return xRoot.Descendants().Where(n => n.Name.LocalName == name);
}
}
答案 2 :(得分:0)
我猜这 LINQ2XML 会帮助你解决问题
XElement doc = XElement.Load("yourStream.xml");
XNamespace s="http://datex2.eu/schema/1_0/1_0";
foreach (var itm in doc.Descendants(s+ "predefinedLocation"))
{
itm;//your required predefinedLocationName node
itm.Element(s+"predefinedLocationName").Element(s+"value").Value;//VMS M60/9084B
}
答案 3 :(得分:0)
说到XPath,我总是发现更小/更短/更简单的XPath表达式更好。我会用这个:
//predefinedLocationSet
这对你有用吗?在XPath测试仪上,它确实对我有用。