【问题标题】:Navigating XML using XPATH with a different namespace使用具有不同命名空间的 XPATH 导航 XML
【发布时间】:2016-02-11 13:20:33
【问题描述】:

我正在努力找出如何导航到使用命名空间的 xml 区域。使用基本的 xpath,我可以很好地导航到消息详细信息节点,但我不确定在进入该块方面我需要做什么,因为里面的所有内容都使用命名空间。请问有人可以帮忙吗?

谢谢

   <?xml version="1.0" encoding="UTF-8"?>
    <Message>
        <MessageList>
            <MessageCount>2</MessageCount>
            <DateTimeStamp>2016-02-11T12:50:26</DateTimeStamp>
            <MessageDetail>
                <MessageID>2332445456767</MessageID>
                <Env:MessageContainer xmlns:Env="http://www.somesite.com/schema/v1.0/envelope" xmlns:BS="http://www.somesite.com/schema/v1.0/BusinessServices">
                    <Env:MessageParties>
public List<String> getRefs(String xmlMessageToSend)
{
    try
    {
        Document doc = createDocument(xmlMessageToSend.getBytes());
        XPath xpath = xPathFactory.newXPath();
        xpath.setNamespaceContext(new NamespaceContext() {

            @Override
            public String getNamespaceURI(String prefix)
            {
                if (prefix == null)
                    throw new NullPointerException("Null prefix");
                else if ("Env".equals(prefix))
                    return "http://www.om.com/schema/v1.0/envelope";
                else if ("BS".equals(prefix))
                    return "http://www.o.com/schema/v1.0/BusinessServices";

                return XMLConstants.NULL_NS_URI;
            }

            @Override
            public Iterator getPrefixes(String namespaceURI)
            {
                throw new UnsupportedOperationException();
            }

            @Override
            public String getPrefix(String namespaceURI)
            {
                throw new UnsupportedOperationException();
            }

        });
        XPathExpression exp = xpath
                .compile("/Message/MessageList/MessageDetail/Env:MessageContainer");
        Node result = (Node)exp.evaluate(doc, XPathConstants.NODE);
        System.out.println(result.getTextContent());
    }
    catch (XPathExpressionException | SAXException | IOException | ParserConfigurationException e)
    {
        e.printStackTrace();
    }

    return new ArrayList<String>();
}

【问题讨论】:

  • 将命名空间前缀与 nodeName 一起使用。例如:: /Env:MessageContainer
  • 您也可以使用一般路径。 //消息详情/*[2]/*[1] ...
  • @Jagrut 没用
  • @Helmer - 这确实有效,但如果有多个消息详细信息节点会如何改变?
  • 目前无法回答这个问题。告诉我们您使用 XPath 的编程语言和库 - 并显示此代码。

标签: java xml xpath


【解决方案1】:

您没有说明您使用什么来导航文档,但通常,API 中应该有一种方法可以让您声明与 Env:MessageContainer 上的名称匹配的名称空间前缀。 .然后您可以在 XPath 中使用该前缀,例如//e:MessageContainer(假设您将 'e' 映射到 "http://www.somesite.com/schema/v1.0/envelope")。

【讨论】:

    【解决方案2】:

    您需要在 XPath 表达式中使用消息前缀。例如,

    //foo:MessageContainer
    

    此前缀不必与原始文档中用于命名空间 URI 的前缀相同。在这里,我使用了前缀 foo,即使它在您的文档中是 Env。只要两个前缀都映射到相同的 URI(本例中为 http://www.somesite.com/schema/v1.0/envelope),XPath 就会匹配。

    您如何将此前缀准确绑定到所需的命名空间 URI,这取决于嵌入 XPath 表达式的宿主语言。例如,在 XSLT 中,您只需在 XSLT 样式表中声明相关前缀,就像在任何其他 XML 文档中一样。相比之下,在 XOM 中,您必须提供一个 XPathContext 对象来相应地映射命名空间前缀。对于其他语言和 API,依此类推。

    【讨论】:

      【解决方案3】:

      您可以通过例如访问您的元素

      //Env:MessageContainer
      

      但要实现这一点,您的xmlns:Env="http://www.somesite.com/schema/v1.0/envelope" xmlns:BS="http://www.somesite.com/schema/v1.0/BusinessServices" 应在&lt;root&gt; 元素中定义,而不是(或附加于)&lt;Env:MessageContainer&gt; 元素中。

      但是如果你不能改变你的源 XML,那么正确的解决方案是使用与上面相同的东西的综合风格:

      //*[local-name()='MessageContainer'][namespace-uri()='http://www.somesite.com/schema/v1.0/envelope']
      

      【讨论】:

        猜你喜欢
        • 2013-01-01
        • 2010-10-08
        • 2021-03-21
        • 1970-01-01
        • 2016-11-30
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        相关资源
        最近更新 更多