В этом примере Java мы изучим разрешение пространства имен XPath в XML-файле с помощью NamespaceContext, который содержит объявления пространств имен и соответствующие использования.
1. XML с пространством имен
Мы создали файл sample.xml и поместили его в classpath для демонстрационных целей.
<ns2:bookStore xmlns:ns2="http://bookstore.com/schemes"><ns2:book id="1"><ns2:name>Data Structure</ns2:name></ns2:book><ns2:book id="2"><ns2:name>Java Core</ns2:name></ns2:book></ns2:bookStore>
2. Реализуйте NamespaceContext для создания NameSpace Resolver
Этот распознаватель пространства имен может использоваться с любым XML-файлом, в котором используются определения пространства имен. Он ищет объявления пространства имен для любого заданного префикса пространства имен, переданного в качестве параметра, внутри самого XML-документа. Поэтому нет необходимости создавать сопоставление пространства имен отдельно.
public class NamespaceResolver implements NamespaceContext{//Store the source document to search the namespacesprivate Document sourceDocument;public NamespaceResolver(Document document) {sourceDocument = document;}//The lookup for the namespace uris is delegated to the stored document.public String getNamespaceURI(String prefix) {if(prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {return sourceDocument.lookupNamespaceURI(null);} else {return sourceDocument.lookupNamespaceURI(prefix);}}public String getPrefix(String namespaceURI) {return sourceDocument.lookupPrefix(namespaceURI);}@SuppressWarnings("rawtypes")public Iterator getPrefixes(String namespaceURI) {return null;}}
3. Использование NamespaceResolver и применение XPath
Теперь мы готовы применить выражение xpath к XML-файлу.
//Want to read all book names from XMLArrayList<String> bookNames = new ArrayList<String>();//Parse XML fileDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setNamespaceAware(true);DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(new FileInputStream(new File("sample.xml")));//Get XPath expressionXPathFactory xpathfactory = XPathFactory.newInstance();XPath xpath = xpathfactory.newXPath();xpath.setNamespaceContext(new NamespaceResolver(doc));XPathExpression expr = xpath.compile("//ns2:bookStore/ns2:book/ns2:name/text()");//Search XPath expressionObject result = expr.evaluate(doc, XPathConstants.NODESET);//Iterate over results and fetch book namesNodeList nodes =(NodeList) result;for(int i = 0; i < nodes.getLength(); i++) {bookNames.add(nodes.item(i).getNodeValue());}//Verify book namesSystem.out.println(bookNames);
Вывод программы:
[Data Structure, Java Core]
4. Полный исходный код для разрешения пространства имен XPath
Это полный исходный код приведенного выше примера.
import java.io.File;import java.io.FileInputStream;import java.util.ArrayList;import java.util.Iterator;import javax.xml.XMLConstants;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.XPathExpression;import javax.xml.xpath.XPathFactory;import org.w3c.dom.Document;import org.w3c.dom.NodeList;public class Main{public static void main(String[] args) throws Exception{//Want to read all book names from XMLArrayList<String> bookNames = new ArrayList<String>();//Parse XML fileDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setNamespaceAware(true);DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(new FileInputStream(new File("sample.xml")));//Get XPath expressionXPathFactory xpathfactory = XPathFactory.newInstance();XPath xpath = xpathfactory.newXPath();xpath.setNamespaceContext(new NamespaceResolver(doc));XPathExpression expr = xpath.compile("//ns2:bookStore/ns2:book/ns2:name/text()");//Search XPath expressionObject result = expr.evaluate(doc, XPathConstants.NODESET);//Iterate over results and fetch book namesNodeList nodes =(NodeList) result;for(int i = 0; i < nodes.getLength(); i++) {bookNames.add(nodes.item(i).getNodeValue());}//Verify book namesSystem.out.println(bookNames);}}class NamespaceResolver implements NamespaceContext{//Store the source document to search the namespacesprivate Document sourceDocument;public NamespaceResolver(Document document) {sourceDocument = document;}//The lookup for the namespace uris is delegated to the stored document.public String getNamespaceURI(String prefix) {if(prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {return sourceDocument.lookupNamespaceURI(null);} else {return sourceDocument.lookupNamespaceURI(prefix);}}public String getPrefix(String namespaceURI) {return sourceDocument.lookupPrefix(namespaceURI);}@SuppressWarnings("rawtypes")public Iterator getPrefixes(String namespaceURI) {return null;}}
Если у вас есть вопросы, пишите их в комментариях.