使用具有預設命名空間的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中文網其他相關文章!