我正在努力找出如何导航到使用命名空间的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>(); }
答案 0 :(得分:0)
您没有说出您用于浏览文档的内容,但通常情况下,API中应该有一种方法可以用来声明匹配的名称空间前缀Env上的那个:MessageContainer。然后,您可以在XPath中使用该前缀,例如//e:MessageContainer
(假设您已将{&#39; e&#39;映射到"http://www.somesite.com/schema/v1.0/envelope"
)。
答案 1 :(得分:0)
您需要在XPath表达式中使用消息前缀。例如,
//foo:MessageContainer
此前缀不必与原始文档中使用的名称空间URI相同。在这里,我使用了前缀foo
,即使它是您文档中的Env
。只要两个前缀都映射到相同的URI(在此示例中为http://www.somesite.com/schema/v1.0/envelope),XPath就会匹配。
如何将此前缀绑定到所需的命名空间URI取决于嵌入XPath表达式的宿主语言。例如,在XSLT中,您只需在XSLT样式表中声明相关的前缀,就像在任何其他XML文档中一样。相反,在XOM中,您必须提供一个XPathContext
对象,该对象相应地映射名称空间前缀。等等其他语言和API。
答案 2 :(得分:0)
您可以通过例如
访问您的元素//Env:MessageContainer
但要实现这一目标,您的xmlns:Env="http://www.somesite.com/schema/v1.0/envelope" xmlns:BS="http://www.somesite.com/schema/v1.0/BusinessServices"
应在<root>
元素中定义,而不是<Env:MessageContainer>
元素(或除此之外)。
但是如果你不能改变你的源XML,那么正确的解决方案就是编写与上面相同的综合风格:
//*[local-name()='MessageContainer'][namespace-uri()='http://www.somesite.com/schema/v1.0/envelope']