remove node

hello, it磗 possible to remove a node or a element by is id?

i have this example:

<book>

<chapter id="um">

<para id ="test">chapter 1. </para>

<para id ="test1">chapter 2. </para>

<para id ="test2">chapter 3. </para>

</chapter>

</book>

and i want to remove a para by is id or remove the chapter by is id too.

is that possible?

[453 byte] By [Taigoa] at [2007-11-27 3:44:26]
# 1
- Traverse to the node and save it: getElementById- Get the parent node: getParentNode- Remove, parentsNode.removeChild (theNodeYouWantToDelete)
kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

> - Traverse to the node and save it: getElementById

>

> - Get the parent node: getParentNode

>

> - Remove, parentsNode.removeChild

> (theNodeYouWantToDelete)

hi! thanks! that works! :)

what I'm trying to do now is, selecting id teste1 what i get is:

<book>

<chapter id="um">

<para id ="teste1">chapter 2. </para>

</chapter>

</book>

its that possible?

Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3
This is what happens when you try to delete a node?A look at code might give me better insight.
kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

> This is what happens when you try to delete a node?

>

> A look at code might give me better insight.

hi!

No. this isn't what happens when i delete a node.

when i delete the node with the id teste1 what a get is:

<book>

<chapter id="um">

<para id ="teste">chapter 1. </para>

<para id ="teste2">chapter 3. </para>

</chapter>

</book>

that is correct.

what i磎 trying to do now is exactly the opposite. i want to select a node with the id teste1 and get this:

<book>

<chapter id="um">

<para id ="teste1">chapter 2. </para>

</chapter>

</book>

i want remove all the siblings . is this possible?

(if you want i can post my code)

Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5

I think I understand what you mean. You are saying if the user makes a selection for id teste1, that will be the one that shows ?

You can remove all the siblings of course. Something tells me that might not be your goal though. I would think you would want to keep a copy of the original. Then again, this all depends on the context if your program.

You can either build the document (see DocumentBuilderFactory and related APIs), or remove its siblings I suppose. You would just make a loop using the same methods we talked about earlier.

Yes, code would help to see the end goal. What is the purpose of the program?

kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 6

Hi!

the propose of my program is:

i have a several chapters in several files. what i磎 trying to do is, make a selection by id of several chapters, or paragraph's, or images, (all by id) and make a single one xml file, that would be my book.

yes, i want to leave a copy of the original.

where's my code... is in the beginning. can you help me?

public class RemoveElementsId{

private static void dump(Document doc) throws TransformerException {

//transformer doc

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer();

transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

transformer.setOutputProperty(OutputKeys.INDENT,"yes");

DOMSource source = new DOMSource(doc);

StreamResult result = new StreamResult(System.out);

transformer.transform(source, result);

}

public static void main (String argv []){

try {

DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();

DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

Document doc = docBuilder.parse (new File("book1.xml"));

//System.out.println("Documento book1 original.");

//dump(doc);

Element element =doc.getElementById("teste2");

//Remover node

element.getParentNode().removeChild(element);

//System.out.println("Documento book1 sem o node teste1.");

//dump(doc);

doc.normalize();

//append to root file

Document doc2 = docBuilder.parse (new File("RootFile.xml"));

//System.out.println("Documento RootFile original.");

//dump(doc2);

Node dup = doc2.importNode(doc.getDocumentElement(), true);

// Insert the copy into doc2

doc2.getDocumentElement().appendChild(dup);

doc.getDocumentElement ().normalize ();

System.out.println("Documento RootFile com o node.");

dump(doc2);

}catch (SAXParseException err) {

System.out.println ("** Parsing error" + ", line "

+ err.getLineNumber () + ", uri " + err.getSystemId ());

System.out.println(" " + err.getMessage ());

}catch (SAXException e) {

Exception x = e.getException ();

((x == null) ? e : x).printStackTrace ();

}catch (Throwable t) {

t.printStackTrace ();

}

}//end

}

Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 7

A few notes.

- check out this tutorial: http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/dom/index.html

It will go through DOM and explain the concepts and a good way to go through the operations. Also, look through the DOM API more.

- try not hardcode any string literals. For example, the input file name should be passed in as an argument to the program.

Your main would have something like this

RemoveElementsById rebi = new RemoveElementsById(args);

and your class would have a constructor that does the initialization.

private String xmlInput;

// ... any other fields you need

// Constructor

public RemoveElementsById(String args[]) {

// this is the name of the xml file you want to parse, I am just assuming here it

// is the first argument you pass

xmlInput = args[0];

// ... any other init you need

}

- your code

element.getParentNode().removeChild(element);

suggestion:

// You get the parent Node, and then you remove the child, which is

// the object you are originally calling the operation on. For safety...

Element parent = (Element)element.getParentNode();

parent.removeChild(element);

- The importNode method can be helpful. The other alternative, and I think in this case should be used is the following

// create a new document. this is a blank document that you need to create

// elements in and populate

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

Document newDoc = builder.newDocument();

// ... later you say

Element newEl = newDoc.createElement ("para");

- if you want to keep a copy of the original, I would suggest not removing any children. Or you can, just make sure that another copy is saved elsewhere int he program, but that sounds dirty to me.

kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 8
hi! thank you very much.i still don't understand how can i remove the siblings from one element.can you be more specific in the code you show me?i磎 very new at Java :( it doesn't help me very much. :(
Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 9

There is no API method that allows you to remove a sibling. You can remove children.

Let's say this is your xml:

<book id="book1">

<chapter id="ch1" name="bla">Chapter 1</chapter>

<chapter id="ch2" name="blabla">Chapter 2</chapter>

</book>

If you want to remove chapter 1, you would say

// get element by id

Element chEl = doc.getElementById ("ch1");

// get the parent. the var parent will now hold the node in memory seperate

// from that in doc

Element parent = (Element)chEl.getParentNode();

// remove the node you want

// this will remove the chapter 1 node from the tree.

parent.removeChild(chEl);

does that help?

kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 10

ok!

its impossible remove the siblings?

look this example please:

<chapter id="asd">

<sect id="asd2">

<para id ="teste">chapter 1. </para>

<para id ="teste1">chapter 2. </para>

<para id ="teste2">chapter 3. </para>

</sect>

<sect id="asd3">

<para id ="um">chapter um.</para>

<para id ="dois">chapter dois. </para>

<para id ="tres">chapter tres. </para>

</sect>

</chapter>

selecting id teste1 i need to get something like:

<chapter id="asd">

<sect id="asd2">

<para id ="teste1">chapter 2. </para>

</sect>

</chapter>

the other sect should not appear.

is this possible?

Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 11
Of course it is possible.If you select a specific id, you will only get that element. If you want that result, you still have to build it yourself, meaning, you still have to create each element and append its children.
kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 12
ok!i don磘 now how but, i will try. :)thank you for every thing.
Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 13
It's in the example code I supplied. Check out the API and read the method specifications.
kdajania at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 14
> It's in the example code I supplied. Check out the> API and read the method specifications.can you be more specific in the code you supplied? sorry, i know I'm being annoying but if you can help me , i will be thankful.
Taigoa at 2007-7-12 8:48:05 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 15

Honestly, I don't know what else to tell you. If you aren't willing to read this stuff and experiment with it, then I can't help you.

http://java.sun.com/webservices/jaxp/dist/1.1/docs/tutorial/dom/4_create.html

This goes through exact steps of how it is done. Give it a minute, see what you can learn.

kdajania at 2007-7-21 20:54:41 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 16

The below method takes a node and removes all the nodes from its parent document that are not part of the ancestor-or-self XPath axis, the node argument being the context node. The return type is void because the node argument is passed by reference.void getAncestorOrSelf(Node node) {

Node parent = node.getParentNode();

if (parent != null) {

NodeList children = parent.getChildNodes();

Node child;

for (int i = 0; i < children.getLength(); i++) {

child = children.item(i);

if (child != node) {

parent.removeChild(child);

i--;

}

getAncestorOrSelf(parent);

}

}

}

prgguya at 2007-7-21 20:54:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 17

hi!! thanks for this great help! thank you!!!

works "almost" perfectly! :)

how can i put this work if i select more than one ID to append to root file? is this possible?

<chapter id="chp">

<sect id="secA">

<para id="a1">texto a1. </para>

<para id="a2">texto a2. </para>

<para id="a3">texto a3. </para>

</sect>

<sect id="secB">

<para id="b1">texto b1. </para>

<para id="b2">texto b2. </para>

<para id="b3">texto b3. </para>

</sect>

<sect id="secC">

<para id="c1">texto c1. </para>

<para id="c2">texto c2. </para>

<para id="c3">texto c3. </para>

</sect>

</chapter>

if i select ID "a2" and ID "secC" want i need to get is:

<chapter id="chp">

<sect id="secA">

<para id="a2">texto a2. </para>

</sect>

<sect id="secC">

<para id="c1">texto c1. </para>

<para id="c2">texto c2. </para>

<para id="c3">texto c3. </para>

</sect>

</chapter>

is this possible?

Taigoa at 2007-7-21 20:54:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 18

Yes, of course it is, but you would be better off using XSLT stylesheets in preference to writing your own code from scratch which would be rather too complicated, provide less flexibility and performance. I have already posted an XSLT stylesheet that meets your requirements. Here it is again, adapted to your previous post:<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="@*|node()">

<xsl:copy>

<xsl:apply-templates select="@*|*[.//*[@id='a2' or @id='secC']]"/>

<xsl:copy-of select="*[@id='a2' or @id='secC']"/>

</xsl:copy>

</xsl:template>

</xsl:stylesheet>

prgguya at 2007-7-21 20:54:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 19
thank you once again!
Taigoa at 2007-7-21 20:54:42 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...