9

I have a very simple xml file that I would like to create a simple function to remove an item from it. Here is my xml file:

    <?xml version="1.0"?>
<book>
  <person>
    <name>Person 1</name>
  </person>
  <person>
    <name>Person 2</name>
  </person>
  <person>
    <name>Person 3</name>
  </person>
  <person>
    <name>Person 4</name>
  </person>
</book>

I simply want to call a method to delete one name from the file. I'm not very familiar with XML but did manage to create a reader and writer but now I'm having trouble creating a method to delete an item from my file.

When I say delete an item I mean:

deleteItem("Person 3");

And then the XML file will change to:

<?xml version="1.0"?>
    <book>
      <person>
        <name>Person 1</name>
      </person>
      <person>
        <name>Person 2</name>
      </person>
      <person>
        <name>Person 4</name>
      </person>
    </book>

What did I do wrong:

public static void removeName(String personName) throws ParserConfigurationException, IOException, SAXException{
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
        Document doc = docBuilder.parse (new File("test.xml"));

        NodeList nodes = doc.getElementsByTagName("person");
        for (int i = 0; i < nodes.getLength(); i++) {       
            Element person = (Element)nodes.item(i);
            Element name = (Element)person.getElementsByTagName("name").item(0);
            String pName = name.getTextContent();
            if(pName.equals(personName)){
                person.getParentNode().removeChild(person);
            }
        }

    }

3 Answers 3

10

Using DOM:

  public static void main(String[] args) throws Exception {
    final String xml =    "<book> " +
        "<person> " +
          "<name>Person 1</name> " +
        "</person> " +
        "<person> " +
          "<name>Person 2</name> " +
        "</person> " +
        "<person> " +
          "<name>Person 3</name> " +
        "</person> " +
        "<person> " +
          "<name>Person 4</name> " +
        "</person> " +
      "</book>";

      DocumentBuilderFactory dbf =
          DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      InputSource is = new InputSource();
      is.setCharacterStream(new StringReader(xml));

      Document doc = db.parse(is);
      deletePerson(doc, "Person 3");
      printXML(doc);
  }

  public static void deletePerson(Document doc, String personName) {
    // <person>
    NodeList nodes = doc.getElementsByTagName("person");

    for (int i = 0; i < nodes.getLength(); i++) {
      Element person = (Element)nodes.item(i);
      // <name>
      Element name = (Element)person.getElementsByTagName("name").item(0);
      String pName = name.getTextContent();
      if (pName.equals(personName)) {
         person.getParentNode().removeChild(person);
      }
    }
  }

  public static void printXML(Document doc) 
  throws TransformerException {
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");

    StreamResult result = new StreamResult(new StringWriter());
    DOMSource source = new DOMSource(doc);
    transformer.transform(source, result);

    String xmlString = result.getWriter().toString();
    System.out.println(xmlString);
  }
Sign up to request clarification or add additional context in comments.

1 Comment

When checking node.getLength() in the loop, you cannot use a for loop with increment.
2

first select the item with the good text.

To do that, use xpath syntax : /book/person[name/text() = "Person 3"]

After that, you will have the node, simply remove it from its parent.

Here is the code (not tested) :

InputSource source = new InputSource(new FileInputStream(##your file##));

XPathFactory builder = XPathFactory.newInstance();
XPath xpath = builder.newXPath();

String label = "Person 3";
XPathExpression exp = xpath.compile("/book/person[name/text() = \"" + label +"\"]");

Node node = (Node) exp.evaluate(source, XPathConstants.NODE);
node.getParentNode().removeChild(node);

Comments

2

Basically you have to parse the document and get the element and remove it.
You can do this using javax.xml.parsers and javax.xml.transform packages.

File file = new File(xmlFile);

xmlfile stores the name of the xml file. Read the file as a document.

  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  DocumentBuilder builder = factory.newDocumentBuilder();
  Document doc = builder.parse(xmlFile);
  TransformerFactory tFactory = TransformerFactory.newInstance();
  Transformer tFormer = tFactory.newTransformer();<br>

Then get the element and remove it as shown below.

Element element = (Element)doc.getElementsByTagName(remElement).item(0);
//  Remove the node
  element.getParentNode().removeChild(element);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.