简体   繁体   English

命名空间遍历

[英]Namespace Traversal

I am trying to parse the following sample piece of XML: 我正在尝试解析以下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>

I specifically need to get at the contents of the top-level predefinedLocation tag. 我特别需要获取顶层预定义位置标签的内容。 By my calculations, the correct XPath should be 根据我的计算,正确的XPath应该是

/soapenv:Envelope/soapenv:Body/d2LogicalModel/payloadPublication/predefinedLocationSet/predefinedLocation

I am using the following C# code to parse the XML: string filename = "content-sample.xml"; 我正在使用以下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);

However, this keeps coming up with no results. 但是,这一直没有结果。 Can anyone shed any light on this, because I feel like I'm banging my head on a brick wall. 任何人都可以阐明这一点,因为我觉得我的头撞在砖墙上。

d2LogicalModel and its descendants are not in the empty namespace but in the "http://datex2.eu/schema/1_0/1_0" namespace. d2LogicalModel及其子代不在空名称空间中,而在“ http://datex2.eu/schema/1_0/1_0”名称空间中。 You need to add this namespace to the namespace manager to be able to select your elements: 您需要将此名称空间添加到名称空间管理器中,以便能够选择您的元素:

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); 

Even if you are using Linq to Xml it's worth using fully qualified names to not select something that happens to have the same local name. 即使您使用的是Linq to Xml,也值得使用完全限定的名称来选择一些碰巧具有相同本地名称的名称。

If you want to avoid dealing with namespaces (using Linq2Xml) 如果要避免处理名称空间(使用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);
    }
}

I guess this LINQ2XML would help u out 我想这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
}

When it comes to XPath, I always find that smaller/shorter/simpler XPath expressions are better. 对于XPath,我总是发现较小/较短/简单的XPath表达式更好。 I would use this: 我会用这个:

//predefinedLocationSet

How's that work for you? 那对你有帮助吗? It certainly does the trick for me on an XPath tester. 在XPath测试仪上,它肯定对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM