2010-07-12 22 views
1
解析XML

我試圖從這個XML刪除SOAPns2節點:是否可以忽略/跳過節點,而在Java中

Document doc = parser.parse(xmlFile); 
NodeList startlist = doc.getChildNodes(); 

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<SOAP-ENV:Body> 
<ns2:createCustomer> 
    <Customer> 
     <CustomerId/> 
     <names> 
      <firstName>fName</firstName> 
      <lastName>lName</lastName> 
      <middleName>nName</middleName> 
      <nickName/> 
      </names> 
     <addressList> 
      <address> 
       <streetInfo> 
        <houseNumber>22</houseNumber> 
        <baseName>Street base name</baseName> 
        <district>kewl district</district> 
        </streetInfo> 
       <zipcode>22231</zipcode> 
       <state>xxx</state> 
       <country>xxxz</country> 
       <primary>true</primary> 
       </address> 
      </addressList> 
     <SSN>561381</SSN> 
     <phone> 
      <homePhone>123123123</homePhone> 
      <officePhone/> 
      <homePhone>21319414</homePhone> 
      </phone> 
     <preferred>true</preferred> 
     </Customer> 
     </ns2:createCustomer> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

在此之前這是可能的我嘗試將其讀回爲String,然後將其寫回XML文件,如下所示:

private void preParsing(String fileName,String ...tags) { 

     try { 

      BufferedReader br = new BufferedReader(new FileReader(new File(fileName))); 
      StringBuilder sb = new StringBuilder(); 
      String line; 

      while ((line = br.readLine()) != null) { 
       for (String string : tags) { 
        if(!line.contains(string)){ 
         sb.append(line); 
         sb.append("\n"); 
        } 
       } 
      }   

      System.out.println(sb.toString()); 

      br.close(); 

     } catch (IOException e) { 
      System.err.println("Error occured: " + e.getMessage()); 
     } 

    } 

它的工作,如果我忽略只有一個像標籤:

preParsing("src/main/resources/test.xml", "SOAP"); 

但是當我通過一個以上標籤的說法忽略/從文件中刪除它沒有工作。我確信有更優雅的方式做到這一點,我想不出任何。

回答

3

一些好的信息,您可以使用的StAX filter

class MyFilter implements EventFilter { 
    private final List<String> filtered = Arrays.asList("SOAP-ENV:Envelope", 
     "SOAP-ENV:Body", "ns2:createCustomer"); 

    @Override 
    public boolean accept(XMLEvent event) { 
    if (event.isStartElement()) 
     for (String elementName : filtered) 
     if (event.asStartElement().getName().getLocalPart().equals(
      elementName)) 
      return false; 
    if (event.isEndElement()) 
     for (String elementName : filtered) 
     if (event.asEndElement().getName().getLocalPart().equals(
      elementName)) 
      return false; 
    return true; 
    } 
} 

用法:

DOMResult result = new DOMResult(); 
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); 
xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); 
XMLEventReader reader = xmlInputFactory 
    .createXMLEventReader(new StreamSource(new File("soap.xml"))); 
reader = xmlInputFactory.createFilteredReader(reader, new MyFilter()); 
TransformerFactory transFactory = TransformerFactory.newInstance(); 
Transformer transformer = transFactory.newTransformer(); 
transformer.transform(new StAXSource(reader), result); 
Document document = (Document) result.getNode(); 

FYI:SOAP-ENV和NS2不是元素;它們是名稱空間前綴。該文檔格式錯誤 - 缺少名稱空間聲明&上面的代碼不是我爲有效的名稱空間文檔編寫的內容。

+0

我得到這個錯誤「錯誤:'前綴'soapenv'的命名空間尚未被聲明'',我該如何解決它? – ant 2010-07-12 20:19:32

+0

我的意思是說SOAP-ENV對不起 – ant 2010-07-12 21:10:37

+0

@ c0mrade - 在StAX解析器中設置「IS_NAMESPACE_AWARE」爲false會禁用名稱空間感知。使用相同的文檔和示例代碼,將刪除所有前綴元素。 XSLT需要名稱空間感知,所以如果你有其他帶有前綴的元素,你需要在有效的文檔上操作或者在生成DOM時避免使用變換器。 – McDowell 2010-07-12 21:34:05

0

處理XML文檔的常用方法是使用XSLT。例如,允許您編寫可以刪除特定命名空間中的任何標記的過濾器等等。

XSLT語言與Java有很大的不同,但是從1.4開始就有一個XSLT處理器(檢查Templates和Transformer類),因此得到了很好的支持。

+0

謝謝你的回答,你可以提供一些鏈接讓我開始 – ant 2010-07-12 21:11:25