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");
Related
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);
Xml parsing for inbetween xml data
I have a XML string in one my java String objects as below:
<Record>
<op>Add</op>
<sensdata>400188711111</sensdata>
<id>4</id>
<a1>1111201090467034</a1>
</Record>
If i need the data between
<Record> </Record>
i.e
<op>Add</op>
<sensdata>4001887XXXXX</sensdata>
<id>4</id>
<a1>1111201090467034</a1>
Can I get using the xml parser. I am able to get the values like Add40018871111141111201090467034. But not with tags.
Below is my code snippet
ByteArrayInputStream stream = new ByteArrayInputStream("<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>".getBytes());
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(stream);
NodeList sensdata = document.getDocumentElement().getElementsByTagName("sensdata");
String sensitiveData = sensdata.item(0).getTextContent();
Editing my question with the Solution i have tried:
I did as below:
ByteArrayInputStream stream = new ByteArrayInputStream(toBeParsed.getBytes());
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(stream);
NodeList XmlTagNodeList = document.getDocumentElement().getElementsByTagName(XmlTag);
Document newXmlDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
for (int i = 0; i < XmlTagNodeList.getLength(); i++) {
Node node = XmlTagNodeList.item(i);
Node copyNode = newXmlDocument.importNode(node, true);
newXmlDocument.appendChild(copyNode);
}
DOMImplementationLS domImplementationLS = (DOMImplementationLS) newXmlDocument.getImplementation();
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
record = lsSerializer.writeToString(newXmlDocument);
System.out.println(record);
It prints record prepended with xml tag for every record.
Kindly let me know, is it a good way to do it? And I do not require xml tag. How to get rid of this?
If you are trying to output the XML literally, with the tags and stuff, you can do it by using the Transformer API available at javax.xml.transform.*
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // I prefer to have the <?xml ?> tag
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // Indent the code
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // Original encoding
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); // Indent 4 spaces
// write the XML of a single node to an OutputStream
transformer.transform(new DOMSource(node), new StreamResult(new OutputStreamWriter(out, "UTF-8")));
Is this what you need?
Edit (looping through the nodes):
// Your previous code
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
StringBuilder builder = new StringBuilder();
NodeList children = newXmlDocument.getChildNodes();
for(int x = 0; x < children.getLength(); x++)
{
Node node = children.item(x);
builder.append(lsSerializer.writeToString(node));
builder.append("\n");
}
System.out.println(builder.toString());
Is that any help?
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);
I've developed a method to insert a new element in a XML File. I'm testing it reading the first element Usuario of the input file and appending it at the end.
Input:
<Usuarios>
<Usuario>
<id>identificador</id>
<email>nn#gmail.com</email>
<rol>profesor</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
<Usuario>
<id>00000000H</id>
<email>pertur#gmail.com</email>
<rol>profesor</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
<Usuario>
<id>970104</id>
<email>kk#gmail.com</email>
<rol>alumno</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
</Usuarios>
Output:
<Usuarios>
<Usuario>
<id>identificador</id>
<email>nn#gmail.com</email>
<rol>profesor</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
<Usuario>
<id>00000000H</id>
<email>pertur#gmail.com</email>
<rol>profesor</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
<Usuario>
<id>970104</id>
<email>kk#gmail.com</email>
<rol>alumno</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
<Usuario>
<id>identificador</id>
<email>nn#gmail.com</email>
<rol>profesor</rol>
<alta>01/01/2012</alta>
<baja>30/08/2021</baja>
</Usuario>
</Usuarios>
What am I doing bad? There are two issues:
1.- The elements in the input are not properly indented y the output file. The transformer don't reindents all the registers?
2.- The new element is properly indented, but the new instance of not.
Ideas?
source:
public void almacenarUsuario(UsuarioNegocio usuario) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new File(directorio + "personas.xml"));
Element nUsuario = (Element) doc.getElementsByTagName("Usuarios").item(0);
Node node = doc.createElement("Usuario");
nUsuario.appendChild(node);
Element nid = doc.createElement("id");
nid.appendChild(doc.createTextNode(usuario.getIdUsuario()));
node.appendChild(nid);
Element nemail = doc.createElement("email");
nemail.appendChild(doc.createTextNode(usuario.getEmail()));
node.appendChild(nemail);
Element nrol = doc.createElement("rol");
nrol.appendChild(doc.createTextNode(usuario.getRol()));
node.appendChild(nrol);
Element nalta = doc.createElement("alta");
nalta.appendChild(doc.createTextNode(usuario.getFecha_alta()));
node.appendChild(nalta);
Element nbaja = doc.createElement("baja");
nbaja.appendChild(doc.createTextNode(usuario.getFecha_baja()));
node.appendChild(nbaja);
// Formatter //
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", new Integer(25));
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount","4");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/opt/icxp1/Temporal/jose/personal/nuevo.xml"));
transformer.transform(source, result);
}
Before transforming,
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
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.