【问题标题】:C# XPath Soap, how to navigate to embedded nodeC# XPath Soap,如何导航到嵌入式节点
【发布时间】:2011-07-01 18:55:33
【问题描述】:

在 C#、Asp.Net 中,我试图在 BISearchResponse 中返回错误节点: 我能够获取在 XMLNode 中返回的 GetWireResult 节点。 如何到达错误节点?

<?xml version="1.0" encoding="utf-8" ?> 
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-     <soap:Body>
-          <GetWireResponse xmlns="http://OpenSolutions.com/">
                <GetWireResult><?xml version="1.0"?> 
                      <BISearchResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
                            <Error xmlns="https://bixg.choicepoint.com/webservices/3.0"> 
                                   <Message>BI System: Failed to Login</Message> 
                                   <Code>536870917</Code>
                             </Error>
                      </BISearchResponse>  
                </GetWireResult> 
            </GetWireResponse>
       </soap:Body>
  </soap:Envelope>

我的代码: XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(result);

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            nsmgr.AddNamespace("ab", "http://OpenSolutions.com/");
            nsmgr.AddNamespace("bg", " https://bixg.choicepoint.com/webservices/3.0");
            nsmgr.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
            nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");

            XmlNode xmlnode = xmlDoc.DocumentElement.SelectSingleNode("/soap:Envelope/soap:Body/ab:GetWireResponse", nsmgr);

这适用于这里。 . 我在这里添加xml,但它只在编辑模式下可见。

<?xml version="1.0" encoding="utf-8" ?> 
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <soap:Body>
- <GetWireResponse xmlns="http://OpenSolutions.com/">
  <GetWireResult><?xml version="1.0"?> <BISearchResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Error xmlns="https://bixg.choicepoint.com/webservices/3.0"> <Message>BI System: Failed to Login</Message> <Code>536870917</Code> </Error> </BISearchResponse></GetWireResult> 
  </GetWireResponse>
  </soap:Body>
  </soap:Envelope>

【问题讨论】:

  • 我将您的 XML 示例放入 {code} 部分。请下次执行此操作,否则 XML 不会(正确)显示。
  • 在编辑模式下,粘贴您的 XML,然后选择它并按“{}”按钮。您将看到代码显示在预览中。然后保存。代码现在将在编辑模式之外正确显示。
  • 如果您将其缩进以使层次结构易于查看,也会有所帮助。
  • 我认为,SOAP 主体 &lt;GetWireResult&gt; 中的内容是经过编码的 XML,因此它不是 XML 的一部分。
  • 既然是 xml 编码,那么一种方法是取消编码,将其加载到 xmlDocument 对象中并继续解析吗?

标签: c# .net xml soap xpath


【解决方案1】:

在调试模式下,当您复制此 XML 时,请尝试选择另一个调试可视化工具,例如“文本可视化器”。您可以点击数据提示中的放大镜图标来选择它。

我认为您的 XML 看起来像:

<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <GetWireResponse xmlns="http://OpenSolutions.com/">
      <GetWireResult>
        &lt;?xml version="1.0"?&gt;
        &lt;BISearchResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
        &lt;Error xmlns="https://bixg.choicepoint.com/webservices/3.0">
        &lt;Message>BI System: Failed to Login&lt;/Message&gt;
        &lt;Code>536870917&lt;/Code&gt;
        &lt;/Error&gt;
        &lt;/BISearchResponse&gt;
      </GetWireResult>
    </GetWireResponse>
  </soap:Body>
</soap:Envelope>

<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <GetWireResponse xmlns="http://OpenSolutions.com/">
      <GetWireResult>
        <![CDATA[
        <?xml version="1.0"?>
        <BISearchResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <Error xmlns="https://bixg.choicepoint.com/webservices/3.0">
            <Message>BI System: Failed to Login</Message>
            <Code>536870917</Code>
          </Error>
        </BISearchResponse>
        ]]>
      </GetWireResult>
    </GetWireResponse>
  </soap:Body>
</soap:Envelope>

没关系。因此,您可以使用以下 XPath 选择 GetWireResult

/soap:Envelope/soap:Body/ab:GetWireResponse/ab:GetWireResult

然后将其内容加载到新的 XML 文档中并获得所需的响应。

【讨论】:

    【解决方案2】:

    你快到了。扩展您的 XPath

    "/soap:Envelope/soap:Body/ab:GetWireResponse"
    

    "/soap:Envelope/soap:Body/ab:GetWireResponse/ab:GetWireResult/ab:BISearchResponse/bg:Error"
    

    但是,中间卡住的额外 XML 序言 &lt;?xml version="1.0"?&gt; 使 XML 格式不正确。我很惊讶它可以被处理。我认为 C# API 应该在 xmlDoc.LoadXml(result) 上抛出异常。

    另一种方法是使用 C# 代码来探索 XML 文档的结构并打印出每个节点的子节点,因为上面的内容不会为您返回任何内容。例如。如果你得到一个"/soap:Envelope/soap:Body/ab:GetWireResponse" 的节点而不是"/soap:Envelope/soap:Body/ab:GetWireResponse/ab:GetWireResult" 的节点,ab:GetWireResponse 有什么文本节点子节点,如果有,它们的值(内容)是什么?这应该可以深入了解 XPath 无法正常工作的原因。

    如果那里有一块未解析(即转义)的 XML,您可以将其复制出来并将其解析为 XML,就像您说的那样,或者只是使用正则表达式搜索您需要的模式...取决于复杂性.

    【讨论】:

    • 不幸的是,当我这样做时不会返回任何内容
    • @user:如果问题是 &lt;ab:GetWireResult&gt; 中的内容实际上被转义了(即使它没有以您粘贴的形式显示),那么您应该得到 @ 的结果987654329@ 而不是“/soap:Envelope/soap:Body/ab:GetWireResponse/ab:GetWireResult/ab:BISearchResponse”。这是你看到的吗?
    • 实际上,我没有得到 ab:GetWireResult 或 ab:GetWireResult/ab:BISearchRespon‌​se 的结果。我只得到 /soap:Envelope/soap:Body/ab:GetWireResponse 的结果
    • @user:请尝试将 XML 保存到文件中,从那里复制并在此处发布(在您的问题中)。我假设您是从浏览器视图中复制它的。
    • 返回的 xml 来自 VS 2010 中的调试会话,我将 POST 的结果捕获在 var request = (HttpWebRequest)WebRequest.Create(uri);所以它不是来自浏览器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2014-10-10
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多