【问题标题】:XPath results to empty stringXPath 结果为空字符串
【发布时间】:2011-11-04 12:43:57
【问题描述】:

以下是我的 XML 文件

<xyzevent xmlns="http://www.xyz.com/common/xyzevent/v1" xmlns:xsi="http://www.w3.org2001XMLSchema-instance">
<header>
 ----
</header>
<subscription xmlns="http://www.xyz.com/common/xyzevent/source/v1">
  <sender></sender>
  <receiver>
    <clientsubscription>
        <servicemap>nanna</servicemap>
    </clientsubscription>
  </receiver>
</subscription> 
</xyzevent>

当我从这个 XML budila org.w3c.dom.Document 并应用带有表达式的 XPathExperssion 时

/xyzevent/subscription/receiver/clientsubscription/servicemap/text()

结果为空字符串。表达式可能有什么问题?

谢谢

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    xyzevent 是你的根元素,所以你只需要使用"/subscription/receiver/clientsubscription/servicemap/text()"

    【讨论】:

      【解决方案2】:

      您的 XML 具有默认命名空间:xmlns="http://www.xyz.com/common/xyzevent/v1",因此您需要在 XML/XPath 引擎中定义它。

      或者使用这个 XPath:

      /*[local-name() = 'xyzevent']
          /*[local-name() = 'subscription']
              /*[local-name() = 'receiver']
                  /*[local-name() = 'clientsubscription']
                      /*[local-name() = 'servicemap']
                          /text()
      

      【讨论】:

        【解决方案3】:

        我在以下链接中评估了您的表达:

        http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

        看来,它选择了“nanna”。

        【讨论】:

          【解决方案4】:

          那是因为您的 XML 文档使用命名空间。 XPath 对命名空间来说真的很烦人。要确认这一点,请从文档中删除两个 xmlns=http://.../v1,然后对未命名空间的、无法验证的 XML 文件运行 XPath 表达式。它会匹配。

          发生的情况是,当您的文档包含 {http://.../v1}:xyzevent 时,您的 XPath 表达式尝试选择 /xyzevent,这不是一回事。

          有多种方法可以解决这个问题。正确的方法是设置NamespaceContext,这样您就可以在XPath 表达式中使用prefix:localName 表示法,并将前缀解析为正确的URI。在xerces docs 和更多elsewhere on StackOverflow 中有一个简短的介绍。 ibm.com 有详细的描述。

          您的NamespaceContext 将包含两个(或更多)映射:

          {
              event => http://www.xyz.com/common/xyzevent/v1
              source => http://www.xyz.com/common/xyzevent/source/v1
          }
          

          然后您的 XPath 表达式可以变为 /event:xyzevent/source:subscription/source:receiver/.../text()

          作为一个讨厌的解决方法,您可以重写您的 xpath 表达式以使用 local-name() 函数进行选择:

          /*[local-name()='xyzevent']/*[local-name()='subscription'/ ...
          

          在这种情况下,表达式匹配本地名称为 xyzevent 的任何元素,无论命名空间 URI 是什么。

          【讨论】:

          • 从两个地方删除 xmlns=http://.../v1 后,我都能获得价值。但是你能解释一下当我们在文档中同时拥有命名空间值时如何构建 NamespaceContext 来获取...
          • @Pokuri 在您的NamespaceContext 中注册两个单独的前缀,例如eventsource 分别使用正确的 URI。您的 XPath 表达式将变为 /event:xyzevent/source:subscription/source:receiver/...
          • 但是 NamespaceContext 需要一个 namespaceURI 和一个或多个前缀。那么如何将两个 NamespaceContext 传递给 XPath.setNamespaceContext(namespaceContext);方法
          • stackoverflow.com/questions/914013/… 上的示例涵盖了这一点。
          • 非常有用的链接。非常感谢。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-09
          • 2011-11-04
          • 2014-04-26
          • 1970-01-01
          相关资源
          最近更新 更多