使用Java更新XML文档

使用Java更新XML文档,java,xml,xpath,Java,Xml,Xpath,在互联网上,我发现了很多关于如何实现这一功能的例子,但在我的情况下,它们似乎都不起作用。我有一个包含XML数据的字符串,我知道结果的XPath应该是什么样子。例如,我有一个xml结构,如下所示: <?xml version="1.0"?> <m:parent xmlns:m="http://www.somescheme"> <doc:header xmlns:doc="http://www.somescheme">

在互联网上,我发现了很多关于如何实现这一功能的例子,但在我的情况下,它们似乎都不起作用。我有一个包含XML数据的字符串,我知道结果的XPath应该是什么样子。例如,我有一个xml结构,如下所示:

   <?xml version="1.0"?>
     <m:parent xmlns:m="http://www.somescheme">
      <doc:header xmlns:doc="http://www.somescheme">
        <doc:documentId>137</doc:documentId>
        <doc:documentDescription>Some Description</doc:documentDescription>  
         <doc:task>
           <doc:id>49</doc:id>
           <doc:name>Some Name</doc:name>
           <doc:description>Some Task Description</doc:description>
           <doc:outcome/>
           <doc:dueDate/>
           <doc:priority>50</doc:priority>
          </doc:task>
        </doc:header>
        <m:otherinfo>234324</m:otherInfo>
      </m:parent>
代码应该与上面类似,但是我没有得到结果

你能指出我遗漏了什么吗

问候
Max

在使用名称空间计算XPATH表达式之前,还需要做两件事

  • 默认情况下,
    DocumentBuilderFactory
    实例不支持命名空间。因此,您必须调用
    setNamespaceAware(true)
  • 创建自己的接口实现,并将其传递给
    XPath
    实例
  • 这里是一个简单的
    NamespaceContext
    实现,作为一个静态内部类。这里只实现了
    getNamespaceURI()
    方法。(请参阅这篇IBMdeveloperWorks文章,了解更多详细信息和替代实现:)

    这里是带有
    DocumentBuilderFactory
    的部分:

    DocumentBuilderFactory documentBuilderFactory = 
        DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    Document doc = documentBuilderFactory.newDocumentBuilder().parse(
        new InputSource("data.xml"));
    
    XPath xpath = XPathFactory.newInstance().newXPath();
    xpath.setNamespaceContext(new MyNamespaceContext());
    NodeList nodes = (NodeList) xpath.evaluate(
        "//m:parent/doc:header/doc:task/doc:outcome", doc,
        XPathConstants.NODESET);
    

    这两个名称空间前缀实际上链接到相同的名称空间URI。事实上,在XPATH表达式中只能使用一个前缀,如
    “//doc:parent/doc:header/doc:task/doc:output”
    ,您不需要在
    命名空间上下文中声明这两个前缀。

    定义“我没有得到结果”考虑模式允许许多<代码> doc:页眉 EntEngsDebug:由于表达式的结果,我没有得到一个NODLIST,因此我不能对列表中的可能的节点进行修改,然后更新,@ GKNICKER,这可能是真的,然而,当我对其中一个值使用getattribute或element时,我确实得到了响应,但要确定第一个值是唯一正确的值并不总是安全的注意:无效的XML
    234324
    :开始标记大小写与结束标记大小写不匹配otherinfo/otherinfo注意到它太晚了,在发布到这里之前必须修改一些值,在真正的xml中使用正确的开始和结束标记谢谢,修复了我的问题//m:父级/doc:标题/doc:任务/doc:结果现在有效
    static class MyNamespaceContext implements NamespaceContext {
      @Override
      public String getNamespaceURI(String prefix) {
        if(prefix == null) {
          throw new IllegalArgumentException();
        } else if(prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
          return XMLConstants.NULL_NS_URI;
        } else if(prefix.equals(XMLConstants.XML_NS_PREFIX)) {
          return XMLConstants.XML_NS_URI;
        } else if(prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
          return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
        } else if(prefix.equals("m")) {
          return "http://www.somescheme";
        } else if(prefix.equals("doc")) {
          return "http://www.somescheme";
        } else {
          return XMLConstants.NULL_NS_URI;
        }
      }
    
      @Override
      public String getPrefix(String namespaceURI) {
        throw new UnsupportedOperationException();
      }
    
      @Override
      public Iterator getPrefixes(String namespaceURI) {
        throw new UnsupportedOperationException();
      }
    }
    
    DocumentBuilderFactory documentBuilderFactory = 
        DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    Document doc = documentBuilderFactory.newDocumentBuilder().parse(
        new InputSource("data.xml"));
    
    XPath xpath = XPathFactory.newInstance().newXPath();
    xpath.setNamespaceContext(new MyNamespaceContext());
    NodeList nodes = (NodeList) xpath.evaluate(
        "//m:parent/doc:header/doc:task/doc:outcome", doc,
        XPathConstants.NODESET);