2012-10-16 77 views
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: 字符串文件名=「內容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); 

但是,這仍然沒有結果。任何人都可以對此有所瞭解,因爲我覺得我正在將我的頭撞在磚牆上。

回答

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它使用完全合格的名稱不選擇發生的事情有相同的地方是值得名稱。

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 
} 
0

當涉及到的XPath,我總是發現小/短/簡單的XPath表達式是更好的。我會用這個:

//predefinedLocationSet 

你的工作怎麼樣?它在XPath測試器中確實對我有用。

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); 
    } 
} 
+0

+ 1..hmm..nice..y使用xnamespace然後.. – Anirudha