簡體   English   中英

使用Java更新XML文檔

[英]Update XML document using Java

在互聯網上,我找到了許多有關如何實現此功能的示例,但是在我看來,這些示例都不起作用。 我有一個包含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>

比如說我需要訪問和更新otherInfo,那么XPath應該是“ m:parent / m:otherInfo”,我應該能夠讀取和設置它。 對於doc:outcome,它將是'm:parent / doc:header / doc:task / doc:outcome'。這是我需要在運行時設置的值。

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
        new InputSource("data.xml"));

    XPath xpath = XPathFactory.newInstance().newXPath();
    NodeList nodes = (NodeList) xpath.evaluate("//m:parent/doc:header/doc:task/doc:outcome", doc,
        XPathConstants.NODESET);

代碼應該像上面一樣,但是我沒有得到結果,

你能指出我想念的東西嗎?

此致Max

您必須另外做兩件事,才能使用命名空間評估XPATH表達式。

  1. 默認情況下, DocumentBuilderFactory實例不支持名稱空間。 因此,您必須調用setNamespaceAware(true)
  2. 創建接口NamespaceContext自己的實現,並將其傳遞給XPath實例。

這里是一個簡單的NamespaceContext實現,它是一個靜態內部類。 此處僅實現getNamespaceURI()方法。 有關更多詳細信息和替代實現,請參閱此IBM developerWorks文章: 將Java語言NamespaceContext對象與XPath結合使用

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 = 
    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:outcome"並且無需在NamespaceContext實現中聲明兩者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM