0

我正在尝试解析以下 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);

但是,这一直没有结果。任何人都可以对此有所了解,因为我觉得我的头撞在了砖墙上。

4

4 回答 4

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 to Xml,也值得使用完全限定名称来避免选择恰好具有相同本地名称的内容。

于 2012-10-16T16:58:32.237 回答
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);
    }
}
于 2012-10-16T16:22:43.870 回答
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
}
于 2012-10-16T15:50:03.280 回答
0

谈到 XPath,我总是发现更小/更短/更简单的 XPath 表达式更好。我会用这个:

//predefinedLocationSet

这对你有什么作用?在 XPath 测试仪上,它确实对我有用。

于 2012-10-16T16:12:57.900 回答