I want to remove the specific nodes from xml file under song tag whose id =2 from the following file in Android (Java):

<music> <song> <id>1</id> <albums_id>1</albums_id> <title>Someone Like You</title> <artist>Adele</artist> <duration>4:47</duration> </song> <song> <id>2</id> <albums_id>1</albums_id> <title>Space Bound</title> <artist>Eminem</artist> <duration>4:38</duration> </song> <song> <id>3</id> <albums_id>1</albums_id> <title>Stranger In Moscow</title> <artist>Michael Jackson</artist> <duration>5:44</duration> </song> </music>

after deletion / removing the nodes (suppose id = 2) expected output needed

<music> <song> <id>1</id> <albums_id>1</albums_id> <title>Someone Like You</title> <artist>Adele</artist> <duration>4:47</duration> </song> <song> <id>3</id> <albums_id>1</albums_id> <title>Stranger In Moscow</title> <artist>Michael Jackson</artist> <duration>5:44</duration> </song> </music> 

Dani AI

Generated

Short answer: either (A) fix the DOM approach that and started (remove nodes safely and write the Document back to disk), or (B) on Android prefer a streaming approach (XmlPullParser + XmlSerializer) to rewrite the file and skip any <song> whose <id> matches the target. Important practical notes: resource XML packaged in res/ or assets/ is read-only at runtime and must be copied to writable storage first; always make a backup; close streams; and use atomic replace (or Android's AtomicFile) when overwriting.

A reliable DOM/XPath flow (works on plain Java and on Android when file is writable): parse into a Document, find matching <song> nodes with an XPath expression, remove them in reverse order (avoid live-NodeList problems), then persist the Document with a Transformer. Example sketch:

// select and remove
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("//song[id='" + idToRemove + "']");
NodeList hits = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
for (int i = hits.getLength() - 1; i >= 0; i--) {
    Node song = hits.item(i);
    song.getParentNode().removeChild(song);
}
// write back
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(destFile)));

If memory or CPU is a concern (large files, Android devices), stream the input and write a new output, skipping matching <song> blocks. The simplest streaming pattern is: on seeing a <song> start, buffer its content (or parse the inner id), decide whether to write that buffered block to the output serializer, and continue. This avoids holding the full tree in memory.

Final cautions: iterate removals in reverse (forward loops can skip nodes), ensure correct encoding (UTF-8), handle file permissions (internal vs external storage), and test on small samples before running on production files.

Recommended Answers

All 3 Replies

What have you tried so far?
What exactly is it that you are stuck with?

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

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

        }

To delete node from xml use function given below

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

  Document doc = db.parse(is);
  deletePerson(doc, id);



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

for (int i = 0; i < nodes.getLength(); i++) {
  Element person = (Element)nodes.item(i);
  // <name>
  Element name = (Element)person.getElementsByTagName("id").item(0);
  String pName = name.getTextContent();
  if (pName.equals(id)) {
     person.getParentNode().removeChild(person);
  }
}
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.