2015-12-15 93 views
1

我有如下的XML文件:的Java查找並刪除子節點

<CourseList> 
<Course> 
    <CourseName>CoreJava</CourseName> 
    <Teacher>Bui Duy Linh</Teacher> 
    <Duration>90 minutes</Duration> 
    <Student> 
     <StudentID>C001</StudentID> 
     <StudentName>Nam</StudentName> 
     <DateRegister>15/11/2016</DateRegister> 
    </Student> 
    <Student> 
     <StudentID>C002</StudentID> 
     <StudentName>Vi</StudentName> 
     <DateRegister>13/11/2016</DateRegister> 
    </Student> 
</Course> 

而且我想刪除ID爲C001的學生,但我的搜索功能似乎返回null

public static Node searchByID(String id, Document doc) { 
    try { 
     XPathFactory xpf = XPathFactory.newInstance(); 
     XPath xp = xpf.newXPath(); 
     NodeList list = (NodeList) xp.evaluate("CourseList/Course/Student/StudentID", doc, XPathConstants.NODESET); 
     for (int i = 0; i < list.getLength(); i++) { 
      String content = list.item(i).getTextContent(); 
      if (content.equalsIgnoreCase(id)) { 
       Node p = list.item(i).getParentNode(); 
       return p; 
      } 
     } 

    } catch (XPathExpressionException ex) { 
     Logger.getLogger(AssignmentXML.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    return null; 
} 

有沒有辦法解決它?我應該使用DOM嗎?感謝任何人的幫助

+0

你調試代碼? –

+0

是的,內容確實返回C001,並且我設置了id = C001,但由於某種原因它仍然返回null – user3676506

+0

我試圖運行您的代碼。正確的結果(學生節點)已返回。我只在XML的末尾添加了「」。 – saka1029

回答

0

你說它返回null,但它不。它返回Node具有給定ID的<Student>節點的對象。如果您打印的節點上,您可以:

[Student: null] 

也就是說空值,而是一個Node對象,具有toString()方法是這樣的:

public String toString() { 
    return "["+getNodeName()+": "+getNodeValue()+"]"; 
} 

而且根據Nodejavadoc對於Element節點:

  • nodeName「一樣Element.tagName」
  • nodeValue「空」

如果你真的改變了這個節點中使用的文字:

TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
Transformer transformer = transformerFactory.newTransformer(); 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
transformer.transform(new DOMSource(node), new StreamResult(System.out)); 

您將獲得:

<Student> 
     <StudentID>C001</StudentID> 
     <StudentName>Nam</StudentName> 
     <DateRegister>15/11/2016</DateRegister> 
    </Student> 
1

那麼,結果沒有錯的搜索,但與刪除功能。 我的舊代碼:

Node delNode = searchByID(id, doc); 
doc.getDocumentElement().removeChild(delNode); 

只刪除文檔,節點不是元素中的節點。我這樣做是爲了解決:

Node delNode = searchByID(id, doc); 
delNode.getParentNode().removeChild(delNode); 

感謝你們反正幫助:)

0

對於OP和未來的讀者,需要考慮到重組或重新設計的XML文檔時使用XSLT。沒有循環或如果/然後邏輯是必要的。 XSLT是一種原生的專用語言,專爲此確切需要而設計。與通用語言(包括C#,Python,Perl,PHP和VB)一樣,Java也維護XSLT 1.0處理器。下面是OP的請求的一個工作示例。

XSLT腳本(保存爲.xsl或。XSLT在Java中使用)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <!-- Identity Transform --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Removes all Student nodes with C001 ID condition --> 
    <xsl:template match="Student[StudentID='C001']"/> 

</xsl:transform> 

的Java腳本

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 

import javax.xml.transform.*; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.transform.OutputKeys; 

import java.io.File; 
import java.io.IOException; 
import java.net.URISyntaxException; 

import org.w3c.dom.Document; 
import org.xml.sax.SAXException; 

public class CourseList { 
    public static void main(String[] args) throws IOException, URISyntaxException, 
                SAXException, 
                ParserConfigurationException, 
                TransformerException { 

     // LOAD XML AND XSL DOCUMENTS 
     String inputXML = "C:\\Path\\To\\Input.xml"; 
     String xslFile = "C:\\Path\\To\\XSLTScript.xsl"; 
     String outputXML = "C:\\Path\\To\\Output.xml";         

     DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();    
     DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
     Document doc = docBuilder.parse (new File(inputXML)); 
     Source xslt = new StreamSource(new File(xslFile)); 

     // XSLT TRANSFORMATION WITH PRETTY PRINT 
     TransformerFactory prettyPrint = TransformerFactory.newInstance(); 
     Transformer transformer = prettyPrint.newTransformer(xslt); 

     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
     transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); 
     transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
     transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
     transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
     transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");       

     DOMSource source = new DOMSource(doc); 
     StreamResult result = new StreamResult(new File(outputXML));   
     transformer.transform(source, result); 
    } 
} 

輸出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<CourseList> 
    <Course> 
     <CourseName>CoreJava</CourseName> 
     <Teacher>Bui Duy Linh</Teacher> 
     <Duration>90 minutes</Duration> 
     <Student> 
      <StudentID>C002</StudentID> 
      <StudentName>Vi</StudentName> 
      <DateRegister>13/11/2016</DateRegister> 
     </Student> 
    </Course> 
</CourseList>