1

java - xpath - pom.xml

我正在使用以下 pom.xml 文件作为 xml dom 资源,我想在<version>不迭代代码的情况下获取标记的值,这就是我使用 xpath 的原因,但我猜我的 xpath express 不正确,这就是它没有返回任何值的原因。任何帮助表示赞赏

爪哇代码

    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true);

    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse("C:\\projects\\pom.xml");
    XPath xpath = XPathFactory.newInstance().newXPath();

    XPathExpression expr = xpath.compile("project/version");
    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getNodeValue());
    }

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dc.app</groupId>
  <artifactId>rum</artifactId>
  <packaging>war</packaging>
  <version>12.54-SNAPSHOT</version>
  <name>rum</name>
  <description>rum</description>
</project>
4

1 回答 1

4

制作一个javax.xml.NamespaceContext并将其提供给您的 xpath:

xpath.setNamespaceContext(ctx);

所以:

DocumentBuilderFactory domFactory = DocumentBuilderFactory
        .newInstance();
domFactory.setNamespaceAware(true);

DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("blah.pom");
XPath xpath = XPathFactory.newInstance().newXPath();
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("pom", "http://maven.apache.org/POM/4.0.0");

xpath.setNamespaceContext(
        new NamespaceContextImpl("http://maven.apache.org/POM/4.0.0", 
                namespaces));

XPathExpression expr = xpath.compile("/pom:project/pom:version");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
    System.out.println(nodes.item(i).getTextContent());
}

产量:

12.54-SNAPSHOT

编辑:命名空间上下文的实现:

public class NamespaceContextImpl implements NamespaceContext {
   private final Map<String, String> namespaces;
   private final String defaultNamespaceURI;

   public NamespaceContextImpl(String defaultNamespaceURI,
                               Map<String, String> namespaces) {
      this.defaultNamespaceURI = defaultNamespaceURI;
      this.namespaces = namespaces;
   }

   public Iterator getPrefixes(String namespaceURI) {
      throw new IllegalStateException("Not Implemented.");
   }

   public String getPrefix(String namespaceURI) {
      throw new IllegalStateException("Not Implemented.");
   }

   public String getNamespaceURI(String prefix) {
      if (prefix == null) {
         throw new IllegalArgumentException();
      }
      if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
         return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
      }
      if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {
         return XMLConstants.XML_NS_URI;
      }
      if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
         return defaultNamespaceURI;
      }
      String result = namespaces.get(prefix);
      if (result == null) {
         result = XMLConstants.NULL_NS_URI;
      }
      return result;
   }
}
于 2013-01-15T20:39:32.547 回答