使用内联默认命名空间在文档中查询

时间:2014-03-14 17:03:28

标签: c# xml xpath

我正在尝试/努力查询getCompanyListResponse-Tag(上面的每个标记都可以在以下XML结构中使用namespacemanager和" soap"前缀):

<?xml version=”1.0” encoding=”UTF-8”?> 
<soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”> 
  <soap:Header /> 
  <soap:Body> 
    <getCompanyListResponse xmlns=”http://test.org/schema”>
      <company> 
        <id>12345</id> 
        <address> 
          <role>LOCATION</role>
        </adress>
      </company>
    </getCompanyListResponse>
  </soap:Body>
</soap:Envelope>

不幸的是,我无法更改任何XML,因为XML是Web服务的响应,我无法影响。 遗憾的是,将默认命名空间添加到XMLNamespacemanager并不起作用。 关于如何使用local-name函数,我没有找到足够的答案。

Stream responseStream = response.GetResponseStream();
XPathDocument compDoc = new XPathDocument(responseStream);
XPathNavigator root =  compDoc.CreateNavigator();

XmlNamespaceManager resolver = new XmlNamespaceManager(root.NameTable);
resolver.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
resolver.AddNamespace(String.Empty, "http://test.org/schema");
resolver.AddNamespace("null", "http://test.org/schema");
root.MoveToFirstChild();
XPathNavigator body = root.SelectSingleNode("[/local-name()='soap:Envelope/soap:Body/getCompanyListResponse']", resolver);

使用上面代码中的最后一行,我得到了Exception:&#34; Expression必须导致节点集&#34;(或者接近那个,因为我在德语中使用visual studio,这是我的尝试翻译)

2 个答案:

答案 0 :(得分:0)

在我看来,你正试图读取XML流,但如果我不理解你,我道歉。 在我看来,XmlReader是适合这项工作的合适工具。

XmlReader http://msdn.microsoft.com/en-us/library/system.xml.xmlreader(v=vs.110).aspx

var reader = XmlReader.Create(responseStream);
var xmlnsString = string.Empty;
string id;
while(reader.Read()){
if(reader.IsStartElement()){
    switch(reader.Name){
        case("getCompanyListResponse") : xmlnsString = reader.GetAttribute("xmlns"); 
        //list any name of a node you want to work on here
        case("id") : id = reader.ReadString();
        default: break;


    }

}    

}

答案 1 :(得分:0)

您需要在路径中使用前缀来寻址默认命名空间中的元素:

XPathDocument compDoc = new XPathDocument(responseStream);
XPathNavigator root =  compDoc.CreateNavigator();

XmlNamespaceManager resolver = new XmlNamespaceManager(root.NameTable);
resolver.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
resolver.AddNamespace("ts", "http://test.org/schema");

XPathNavigator comp = root.SelectSingleNode("/soap:Envelope/soap:Body//ts:company", resolver);

string id = comp.SelectSingleNode("ts:id").Value;

你在没有步骤的谓词中使用local-name()的尝试也无法工作,但无论如何都没有必要。