デフォルトの名前空間を持つ XML ドキュメントに XPath を使用する
デフォルトの名前空間を備えた XML ドキュメントを操作する場合、XPath 式を利用するのは難しいように思えるかもしれません。名前空間 URI を明示的に宣言する必要はありません。ただし、この状況に対処するアプローチがあります。
Setting Namespace Aware to False
元の質問で述べたように、最初の理解は、namespaceAware を 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 式
デニスは、元の 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 中国語 Web サイトの他の関連記事を参照してください。