Reputation: 31
I am new in Java and XML. I need to modify a part of this XML file using a Java program :
<?xml version="1.0" encoding="UTF-8"?>
<Traduction>
<Entrée>
<Word1>Word1</Word1>
<N1>0</N1>
<N2>0</N2>
<Word2>Word2</Word2>
</Entrée>
<Sortie>
<Word1>Word1</Word1>
<N1>0</N1>
<N2>0</N2>
<Word2>Word2</Word2>
</Sortie>
</Traduction>
I wanted to use this code in Eclipse :
try {
String filepath = "/home/user/Trad/ex1.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(filepath);
Node Traduction = document.getChildNodes().item(0);
Node Sortie = Traduction.getChildNodes().item(1);
Sortie.getChildNodes().item(0).setTextContent("AAA");
Sortie.getChildNodes().item(1).setTextContent("001");
Sortie.getChildNodes().item(2).setTextContent("002");
Sortie.getChildNodes().item(3).setTextContent("BBB");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
}
catch (ParserConfigurationException pce) {
pce.printStackTrace();
}
catch (TransformerException tfe) {
tfe.printStackTrace();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
catch (SAXException sae) {
sae.printStackTrace();
}
But I get this result, which is not what I want :
<?xml version="1.0" encoding="UTF-8" standalone="no"?><Traduction>
<Entrée>AAA<Word1>001</Word1>002<N1>BBB</N1>
<N2>0</N2>
<Word2>Word2</Word2>
</Entrée>
<Sortie>
<Word1>Word1</Word1>
<N1>0</N1>
<N2>0</N2>
<Word2>Word2</Word2>
</Sortie>
</Traduction>
I would like to get :
<?xml version="1.0" encoding="UTF-8"?>
<Traduction>
<Entrée>
<Word1>Word1</Word1>
<N1>0</N1>
<N2>0</N2>
<Word2>Word2</Word2>
</Entrée>
<Sortie>
<Word1>AAA</Word1>
<N1>001</N1>
<N2>002</N2>
<Word2>BBB</Word2>
</Sortie>
</Traduction>
What should I modify in my Java code to get this ?
Upvotes: 2
Views: 287
Reputation: 8358
As already suggested, Dom Node can be of any type. You can use getElementsByTagName
method to be sure of that.
E.g.:
try {
String filepath = "/home/user/Trad/ex1.xml";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(filepath);
Element sortie = (Element) document.getElementsByTagName("Sortie").item(0);
sortie.getElementsByTagName("Word1").item(0).setTextContent("AAA");
sortie.getElementsByTagName("N1").item(0).setTextContent("001");
sortie.getElementsByTagName("N2").item(0).setTextContent("002");
sortie.getElementsByTagName("Word2").item(0).setTextContent("BBB");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
}
catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
}
Upvotes: 2
Reputation: 7166
The trick is that DOM nodes can be other than the element nodes. I.e. for the whitespaces between <Entree>
and <Word1>
it creates a TextNode
. You need to go through the NodeList
and check for node name or node type.
In the code example you can see example for both. Please note that this code is a bit unstructured. For production quality code you might want to refactor it a little.
Node Traduction = document.getChildNodes().item(0);
NodeList traductionChildNodes = Traduction.getChildNodes();
Node Sortie = null;
for (int i = 0; i < traductionChildNodes.getLength(); i++) {
Node node = traductionChildNodes.item(i);
// here we check the node name
if ("Sortie".equals(node.getNodeName())) {
Sortie = node;
break;
}
}
NodeList sortieChildNodes = Sortie.getChildNodes();
// we got the texts in an array so we can access them one after another
String[] texts = new String[] {"AAA", "001", "002", "BBB"};
// i is for the nodes, j is for the
for (int nodeIndex = 0, textIndex = 0; nodeIndex < sortieChildNodes.getLength(); nodeIndex++) {
Node node = sortieChildNodes.item(nodeIndex);
// here we check the node type
if (node.getNodeType() == Node.ELEMENT_NODE) {
node.setTextContent(texts[textIndex++]);
}
}
Alternatively, you might consider using XPath because that makes ad-hoc XML processing a little more intuitive.
Upvotes: 1