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>

特に、最上位の definedLocation タグの内容を取得する必要があります。私の計算では、正しい XPath は

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

次の C# コードを使用して 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

XPath に関して言えば、小さい/短い/単純な XPath 式の方が優れていることが常にわかります。私はこれを使用します:

//predefinedLocationSet

それはあなたにとってどのように機能しますか?XPathテスターで私にとっては確かにうまくいきます。

于 2012-10-16T16:12:57.900 に答える
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 に答える