Java查找并删除子节点

时间:2015-12-15 02:24:15

标签: java xml xpath

我有一个XML文件如下:

<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吗?感谢任何人的帮助

3 个答案:

答案 0 :(得分:1)

嗯,结果是搜索没有错,但是删除功能。 我的旧代码:

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

仅删除文档中的Node,而不删除节点的Element。我这样做是为了解决:

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

谢谢你们帮助我们:)

答案 1 :(得分:0)

你说它返回null,但它没有。它为具有给定ID的a2节点返回A个对象。如果您打印节点,则会得到:

Node

那是一个空值,而是一个<Student>对象,使用[Student: null] 方法,如下所示:

Node

根据toString() javadoc public String toString() { return "["+getNodeName()+": "+getNodeValue()+"]"; } 节点:

  • Node &#34;与Element.tagName相同&#34;
  • Element &#34; null&#34;

如果您实际使用以下方法将节点转换为文本:

nodeName

你会得到:

nodeValue

答案 2 :(得分:0)

对于OP和未来的读者,在需要重构或重新设计XML文档时,请考虑使用XSLT。不需要循环或if / then逻辑。 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>
相关问题