使用具有默认命名空间的 XML 文档的 XPath
使用具有默认命名空间的 XML 文档时,使用 XPath 表达式可能看起来很困难无需显式声明命名空间 URI。不过,有一些方法可以解决这种情况。
将命名空间感知设置为 False
正如原始问题中提到的,最初的理解是在DocumentBuilderFactory 将消除使用命名空间 URI 的需要。但是,这种方法不适合具有默认命名空间的文档。默认命名空间需要显式处理。
利用 NamespaceContext
另一种解决方案是在 XPath 执行期间使用 NamespaceContext。这允许您将前缀与 XPath 表达式中的命名空间相关联。使用的前缀可以与 XML 文档中定义的前缀不同。
这是实现此方法的示例:
<code class="java">import javax.xml.namespace.NamespaceContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; public class Demo { public static void main(String[] args) { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); try { DocumentBuilder builder = domFactory.newDocumentBuilder(); Document dDoc = builder.parse("E:/test.xml"); XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(new MyNamespaceContext()); NodeList nl = (NodeList) xPath.evaluate("/ns:root/ns:author", dDoc, XPathConstants.NODESET); System.out.println(nl.getLength()); } catch (Exception e) { e.printStackTrace(); } } private static class MyNamespaceContext implements NamespaceContext { public String getNamespaceURI(String prefix) { if("ns".equals(prefix)) { return "http://www.mydomain.com/schema"; } return null; } public String getPrefix(String namespaceURI) { return null; } public Iterator getPrefixes(String namespaceURI) { return null; } } }</code>
在此示例中,提供的 NamespaceContext 将 'ns' 前缀映射到XML 文档中使用的命名空间 URI。
修订的 XPath 表达式
Dennis 正确地指出原始 XPath 表达式“/root/author”是不正确的。对于具有默认命名空间的文档,正确的表达式应该是“/ns:root/ns:author”。这与代码中新引入的命名空间前缀一致。
命名空间感知的简化
有趣的是,将namespaceAware设置为true并省略NamespaceContext似乎还提供了期望的结果。下面的代码演示了这一点:
<code class="java">import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; public class Demo { public static void main(String[] args) { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); try { DocumentBuilder builder = domFactory.newDocumentBuilder(); Document dDoc = builder.parse("E:/test.xml"); XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nl = (NodeList) xPath.evaluate("/root/author", dDoc, XPathConstants.NODESET); System.out.println(nl.getLength()); } catch (Exception e) { e.printStackTrace(); } } }</code>
在这种情况下,可以使用熟悉的 XPath 表达式“/root/author”,因为在处理过程中会识别并暗示文档的命名空间。
以上是如何使用 XPath 处理具有默认命名空间的 XML 文档?的详细内容。更多信息请关注PHP中文网其他相关文章!