Delete a node and its elements from an XML file in java - java

i have the following xml :
<table1>
<row0>
<column1>String</column1>
<column2>int</column2>
</row0>
<row1>
<column1>aa</column1>
<column2>65432</column2>
</row1>
<row2>
<column1>ww</column1>
<column2>1111</column2>
</row2>
<row3>
<column1>fff</column1>
<column2>333</column2>
</row3>
<row4>
<column1>jj</column1>
<column2>2</column2>
</row4>
</table1>
and i want to delete the node row3 and its elements. I am writing that XML file in java.how to do that?
i saw this code in another post but couldn't understand it
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document document = dbf.newDocumentBuilder().parse(new File("input.xml"));
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile("//A/B[C/E/text()=13]");
Node b13Node = (Node) expression.evaluate(document, XPathConstants.NODE);
b13Node.getParentNode().removeChild(b13Node);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(System.out));
}

This code snippet should do what you want to. If you just want to remove the row3 element from your tree you don't have to use (and understand) the overmighty XPATH!
// -------------- building the document out of the file -----------------
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document document = dbf.newDocumentBuilder().parse(new File("input.xml"));
//------------------------------------------------------------------------
// -------------- finding the right node and removing it -----------------
Element table = document.getDocumentElement();
Node row3 = table.getElementsByTagName("row3").item(0);
table.removeChild(row3);
//------------------------------------------------------------------------
// -------------- printing the resulting tree to the console -------------
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(System.out));
//------------------------------------------------------------------------

Related

how to add new node under a specific node in dom4j JAVA

I want to generate flexiField tags and add it to current xml file.
Here is My xmlFile.
<com.model.FlexiFieldList>
<flexiFields>
<flexiField>
<fieldDesc>BL</fieldDesc>
<fieldName>BL</fieldName>
<fieldType>FREE_TEXT</fieldType>
<fieldTypeDataStr/>
<sensitive>false</sensitive>
<value>True</value>
<valueType>String</valueType>
</flexiField>
</flexiFields>
</com.model.FlexiFieldList>
I want to add new flexiField and I have this Java Code but When I run my code, it adds flexiField node under <com.model.FlexiFieldList> element
I know that in Element root = document.getDocumentElement(); part we show that we will add new node to root location but I couldnt find any way to change it
Actually My question is that how can I change root path so when I run root.appendChild(newFlexiField); it will add new flexiField node under flexiFields node
File file = new File("C:/Users/xxx/Desktop/ff.xml");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
Element root = document.getDocumentElement();
Collection<FlexiField> flexiFields = new ArrayList<FlexiField>();
flexiFields.add(new FlexiField());
for (FlexiField flexiField : flexiFields) {
// server elements
Element newFlexiField = document.createElement("flexiField");
Element name = document.createElement("fieldDesc");
name.appendChild(document.createTextNode(flexiField.fieldDesc()));
newFlexiField.appendChild(name);
Element port = document.createElement("fieldName");
port.appendChild(document.createTextNode(flexiField.fieldName()));
newFlexiField.appendChild(port);
root.appendChild(newFlexiField);
}
DOMSource source = new DOMSource(document);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
Assumming you have only one <flexiFields> element in you xml file you can try this:
File file = new File("C:/Users/xxx/Desktop/ff.xml");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
Element root = document.getDocumentElement();
// to print your root element
System.out.println("\n*************root************");
System.out.println(root.getNodeName());
// to find the flexiFields
Node firstChild=root.getFirstChild();
while (firstChild != null && firstChild.getNodeType() != Node.ELEMENT_NODE)
{
firstChild = firstChild.getNextSibling();
}
System.out.println(firstChild.getNodeName());
Collection<FlexiField> flexiFields = new ArrayList<FlexiField>();
flexiFields.add(new FlexiField());
for (FlexiField flexiField : flexiFields) {
// server elements
Element newFlexiField = document.createElement("flexiField");
Element name = document.createElement("fieldDesc");
name.appendChild(document.createTextNode(flexiField.fieldDesc()));
newFlexiField.appendChild(name);
Element port = document.createElement("fieldName");
port.appendChild(document.createTextNode(flexiField.fieldName()));
// append your child
newFlexiField.appendChild(port);
firstChild.appendChild(newFlexiField);
}
DOMSource source = new DOMSource(document);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult result = new StreamResult(file);
transformer.transform(source, result);

delete child and return carriage from xml

I have an xml file, and sometimes I have to delete some nodes.
This is my code:
String xmlProduct = ""; //my xml above
if(!xmlProduct.equals("")){
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlProduct));
Document dom;
DocumentBuilderFactory dbf = (DocumentBuilderFactory) DocumentBuilderFactory.newInstance();
DocumentBuilder db = (DocumentBuilder) dbf.newDocumentBuilder();
dom = db.parse(is);
dom.normalize();
//delete property
NodeList nodoProperty = dom.getDocumentElement().getElementsByTagName("Property");
for(int i=0; i<nodoProperty.getLength(); i++){
Node nodoBorrar = nodoProperty.item(i);
nodoRaizXML.item(0).removeChild(nodoBorrar);
}
}
//Convert to xml format
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(dom), new StreamResult(writer));
This is an example of my xml:
<Deal>
<SelectedDeal>+1</SelectedDeal>
</Deal>
<Property>
<PropertyId>8215</PropertyId>
<HPIValueChanged>1</HPIValueChanged>
</Property>
<FundBooking>
<ProductCode>J128R?</ProductCode>
<ControlNumber> </ControlNumber>
</FundBooking>
And this is what I got when executing:
<Deal>
<SelectedDeal>+1</SelectedDeal>
</Deal>
<FundBooking>
<ProductCode>J128R?</ProductCode>
<ControlNumber> </ControlNumber>
</FundBooking>
the tag is deleted, but I need to delete its space in the file.
How can I do this
This is the quick & dirt solution :
xmlProduct = xmlProduct.replaceAll("\n", "").replaceAll("\r", "");
//...
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

Create namespace in dom element issue

Im trying to create XML document with DOM APi's and when i use the following code I got the
expect result
Element rootTreeNode = document.createElementNS("http://schemas.microsoft.com/ado/2007","ex" + ":Ex")
this is the output with tags in output console
ex:Ex Version="1.0" xmlns:ex="http://schemas.microsoft.com/ado/2007"/
Now I want to add to this element the following
**xmlns:gp**="http://www.pst.com/Protocols/Data/Generic"
and I dont succeed with the xmlns:gp i have tried to use
the like the following
rootTreeNode.setAttributeNS("xmlns" ,"gp","http://www.pst.com/Protocols/Data/Generic")
and i have got it like the folloing
**xmlns:ns0="xmlns"** **ns0:gp**="http://www.pst.com/Protocols/Data/Generic"
and if put null in the first parameter
rootTreeNode.setAttributeNS(null ,"gp","http://www.pst.com/Protocols/Data/Generic")
I get just gp with the URL without the xmlns .
what am i doing wrong here ?
Thanks!!!
Complete test:
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element root = doc.createElementNS("http://schemas.microsoft.com/ado/2007","ex" + ":Ex");
root.setAttributeNS("http://www.w3.org/2000/xmlns/" ,"xmlns:gp","http://www.pst.com/Protocols/Data/Generic");
doc.appendChild(root);
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
String xmlString = sw.toString();
System.out.println("Xml:\n\n" + xmlString);

parsing the xml to get the root element and then add a tag dynamically under the root tag

I want to parse the xml file to get the root element. Then append add the tag named first-name under that root tag. How do I do this ? This is what I have been doing right now :
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element blobKey_E = document.createElement("first-name");
blobKey_E.appendChild( document.createTextNode( name ) );
// NOW APPEND blobKey_E to the root element
// After getting the root element from the xml in some directory
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File("/home/non-admin/NetBeansProjects/Personal Site_Testers/web/xml/xml_1.xml"));
transformer.transform(source, result);
Element root = document.getDocumentElement();
root.appendChild(document.createElement("first-name"));
Will append first-name to the end of the DOM tree
Inserting into the first position is a little more difficult...
Element root = document.getDocumentElement();
if (root.hasChildNodes()) {
Node firstChild = root.getFirstChild();
root.insertBefore(document.createElement("first-name"), firstChild);
} else {
// Append to as per previous example
}
UPDATE
Eleement firstName = document.createElement("first-name");
firstName.setTextContent("Henry");

How do I get contents inside an XML Node as String in Java

I am looking for something like this :
<Node1>
<Child2 attr1="abc">
<Child3 attr2="xyz">
<Node1>
From Node1 , I want to get the contents inside the node as text. The output I want is
"<Child2 attr1="abc"><Child3 attr2="xyz">"
//Parse the input document
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("yourfile.xml"));
//Set up the transformer to write the output string
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty("indent", "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
//Find the first child node
NodeList nl = doc.getDocumentElement().getChildNodes();
DOMSource source = null;
for(int x = 0;x < nl.getLength();x++)
{
Node e = nl.item(x);
if(e instanceof Element)
{
source = new DOMSource(e);
break;
}
}
transformer.transform(source, result);
System.out.println(sw.toString());
}
}
See this question with other possible answers.

Categories