使用XPath 在Java 中透過命名空間查詢XML
當處理包含綁定到命名空間的元素的XML 文件時,使用XPath 查詢可能會變得具有挑戰性。考慮以下範例:
使用預設的「無命名空間」XPath 表達式(如「/workbook/sheets/sheet[1]」)將會失敗。這是因為 XML 文件中的元素綁定到命名空間,而 XPath 表達式中不考慮該命名空間。
解決方案1:註冊命名空間並使用命名空間前綴
建議的方法是使用名稱空間前綴註冊名稱空間,使XPath 更易於閱讀和維護:
NamespaceContext namespaceContext = new NamespaceContext() { @Override public String getNamespaceURI(String prefix) { if (prefix.equals("main")) { return "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; } else if (prefix.equals("r")) { return "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; } return null; } }; XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); xPath.setNamespaceContext(namespaceContext); NodeList nodes = (NodeList) xPath.evaluate("/main:workbook/main:sheets/main:sheet[1]", document, XPathConstants.NODESET);
使用命名空間前綴,XPath 表達式變為“/main:workbook/main:sheets/main:sheet[1]”,它正確地尋址綁定到指定命名空間的元素。
解決方案2:通用匹配和謂詞過濾器
或者,可以透過使用元素的通用匹配和指定所需local-name() 和namespace-uri () 的謂詞過濾器來建構不含命名空間前綴的XPath 表達式:
XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); NodeList nodes = (NodeList) xPath.evaluate("/*[local-name()='workbook' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']" "/*[local-name()='sheets' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']" "/*[local-name()='sheet' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'][1]", document, XPathConstants.NODESET);
此方法很冗長,如果 XML 文件中存在混合詞彙,則可能會帶來風險。
結論
當處理帶有命名空間的 XML 文件時,必須考慮命名空間綁定。透過使用前綴註冊命名空間或精心設計通用 XPath 表達式,可以執行準確可靠的查詢。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3