2015-12-15 89 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>