I am creating a xml file using Java Transformer.The root node has syntax like this:
<AUTO-RESPONSE-DOCUMENT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://someurl">.
I am creating the root node like this:
Document doc = docBuilder.newDocument();
Element ele = doc.createElement("AUTO-RESPONSE-DOCUMENT");
doc.appendChild(ele);
How should i put the above urls in front of AUTO-RESPONSE-DOCUMENT node?
If you mean the namespace attributes: You can set them like all other atributes:
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element ele = doc.createElement("AUTO-RESPONSE-DOCUMENT");
//Add namespace attibutes
ele.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
ele.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
ele.setAttribute("xmlns", "http://someurl");
doc.appendChild(ele);
Put through this Document-To-Text code
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println(xmlString);
It creates that output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<AUTO-RESPONSE-DOCUMENT xmlns="http://someurl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
/**
* #param args
* #throws ParserConfigurationException
*/
public static void main(String[] args) throws Exception {
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element ele = doc.createElement("AUTO-RESPONSE-DOCUMENT");
doc.appendChild(ele);
ele.setAttribute("xmlns", "http://someurl");
ele.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
ele.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), new StreamResult(System.out));
}
Note the namespace for "xmlns" pefix must be exactly as shown.
Related
My XML looks like below and I need to extract multiple ID element in
an output xml:-
<?xml version="1.0" encoding="utf-8"?>
<Stock>
<PIdentification>
<CatalogVersion></CatalogVersion>
<AccountID></AccountID>
<CustomerId></CustomerId>
</ProviderIdentification>
<Product>
<ArticleName>Monitors</ArticleName>
<BaseUnit></BaseUnit>
<Notes></Notes>
<ID>11f13e2e-ae97-45b5-a9a9-23fa7f6bb767</ID>
<ID>b22834c0-a570-4e6b-97c3-5067a14d118d</ID>
<ID>ed458593-5e1a-4dc1-94f0-a66eeef2dd79</ID>
<ID>d25584a9-1db2-48cf-9a70-9b81e5a7e7f2</ID>
</Product>
</Stock>
I have used "Nodelist" to extract "ID" but I am getting just one element
and not all 4, below is the part of the code:-
{
Node IDNode = element.getElementsByTagName("ID").item(0);
IDXml = toStringXml(IDNode , true);
}
I am not able to reiterate for look to get all the IDs, please let me
know how to get all ID, any help is appreciated.
private static String toStringXml(Node elt, boolean xmlDeclaration)
throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
if(xmlDeclaration)
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
DOMSource source = new DOMSource(elt);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
return result.getWriter().toString();
}
You got all id's but you are only looking at first item with .item(id).
Method getElementsByTageName("ID") returns you NodeList so you can got trough all ids for example like that:
File xmlFile = new File("src/main/resources/example.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document element = dBuilder.parse(xmlFile);
NodeList list = element.getElementsByTagName("ID");
for (int i = 0; i < list.getLength(); i++){
Node specificIDNode = list.item(i);
System.out.println(specificIDNode.getTextContent());
}
You have malformed XML displayed in your question. Unclosed <PIdentification> tag on the row 3.
Correct XML code should look like that:
<?xml version="1.0" encoding="utf-8"?>
<Stock>
<ProviderIdentification>
<CatalogVersion></CatalogVersion>
<AccountID></AccountID>
<CustomerId></CustomerId>
</ProviderIdentification>
<Product>
<ArticleName>Monitors</ArticleName>
<BaseUnit></BaseUnit>
<Notes></Notes>
<ID>11f13e2e-ae97-45b5-a9a9-23fa7f6bb767</ID>
<ID>b22834c0-a570-4e6b-97c3-5067a14d118d</ID>
<ID>ed458593-5e1a-4dc1-94f0-a66eeef2dd79</ID>
<ID>d25584a9-1db2-48cf-9a70-9b81e5a7e7f2</ID>
</Product>
</Stock>
And in this case, code, provided by #Penguin74 displays all IDS from your xml (check the picture below).
I'm working with javax.xml & After removing some node:
docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilder = docBuilderFactory.newDocumentBuilder();
document = docBuilder.parse(new File("file_name"));
NodeList tagList = document.getElementsByTagName("tag_name");
tagList.item(0).getParentNode().removeChild(waysList.item(0));
Instead of the removed tag, I have an empty line.
How can avoid this or remove the empty line?
XML file is:
<root>
<tag_name>text</tag_name>
<tag_name>text</tag_name>
<tag_name>text</tag_name>
</root>
EDIT:
If I add tagList.item(0).getParentNode().setTextContent(""); before or after the removeChild I get a NullPointerException.
Thanks,
Indent before the element and the Carriage return after it are text nodes. If you remove an element and there's a text node before or after it, you will see it as whitespace lines.
public static void main(String[] args){
File file=new File(XmlProcessing.class.getResource("InputXml.txt").getFile());
// create a new DocumentBuilderFactory
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
try{
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(file);
System.out.println("Before removing the Node:-");
printDocument(document, System.out);
NodeList tagList = document.getElementsByTagName("tag_name");
Element elemToBeRemoved = (Element)tagList.item( 0 );
Node prevElem = elemToBeRemoved.getPreviousSibling();
if (prevElem != null &&
prevElem .getNodeType() == Node.TEXT_NODE &&
prevElem .getNodeValue().trim().length() == 0) {
elemToBeRemoved.getParentNode().removeChild(prevElem );
}
elemToBeRemoved.getParentNode().removeChild( elemToBeRemoved );
System.out.println("\nAfter removing the node:-");
printDocument(document, System.out);
}catch(Exception excep){
excep.printStackTrace();
}
}
public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "UTF-8")));
}
/** Output:-
Before removing the Node:-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<tag_name>text</tag_name>
<tag_name>text</tag_name>
<tag_name>text</tag_name>
</root>
After removing the node:-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<tag_name>text</tag_name>
<tag_name>text</tag_name>
</root>
*/
currently I'm required to remove a specific node and its child in an XML file
, however I always encountered null pointer exception whenever I'm trying to remove the nodes. The "position" parameter would be the # of node to remove. e.g position 3 should remove reservation id(04113049)and everything under it.
public void removeReservation(int position){
try{
File file = new File("reservations.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
Element element = (Element)doc.getElementsByTagName("reservation").item(position);
element.getParentNode().removeChild(element);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("reservations.xml"));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
}
catch(Exception e){
e.printStackTrace();
}
}
Here are the contents of the xml file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data>
<reservation_list>
<reservation>
<resID>01014664</resID>
<roomNo>0101</roomNo>
<roomType>VIPSuite</roomType>
<noOfGuest>3</noOfGuest>
<bedType>Master</bedType>
<smoking>Y</smoking>
<startDate>121313</startDate>
<endDate>121316</endDate>
<wifi>Y</wifi>
<roomView>Y</roomView>
<availability>Reserved</availability>
<name>Johnny depp</name>
<address>NTU Hall 17 #01-111</address>
<country>Singapore</country>
<gender>Male</gender>
<nationality>Singaporean</nationality>
<contact>92003239</contact>
<creditCardNo>1234567812345678</creditCardNo>
<creditCardCSV>432</creditCardCSV>
<creditCardExpDate>11/16</creditCardExpDate>
<identity>U0000000I</identity>
</reservation>
<reservation>
<resID>11025652</resID>
<roomNo>1102</roomNo>
<roomType>Double</roomType>
<noOfGuest>3</noOfGuest>
<bedType>Master</bedType>
<smoking>Y</smoking>
<startDate>1212</startDate>
<endDate>1213</endDate>
<wifi>Y</wifi>
<roomView>Y</roomView>
<availability>Reserved</availability>
<name>Thomas</name>
<address>Mountbatten #2-12 Garden ave</address>
<country>Singapore</country>
<gender>Male</gender>
<nationality>Singaporean</nationality>
<contact>93482032</contact>
<creditCardNo>1234567812345678</creditCardNo>
<creditCardCSV>588</creditCardCSV>
<creditCardExpDate>3/16</creditCardExpDate>
<identity>U1234567I</identity>
</reservation>
<reservation>
<resID>04113049</resID>
<roomNo>0411</roomNo>
<roomType>VIPSuite</roomType>
<noOfGuest>7</noOfGuest>
<bedType>Master</bedType>
<smoking>Y</smoking>
<startDate>121112</startDate>
<endDate>232333</endDate>
<wifi>Y</wifi>
<roomView>Y</roomView>
<availability>Reserved</availability>
<name>elaine</name>
<address>punggol</address>
<country>Singapore</country>
<gender>Female</gender>
<nationality>Singaporean</nationality>
<contact>12345672</contact>
<creditCardNo>1234123412341234</creditCardNo>
<creditCardCSV>123</creditCardCSV>
<creditCardExpDate>1212</creditCardExpDate>
<identity>S96777777777F</identity>
</reservation>
</reservation_list>
</data>
First, filtering using item() is zero-based ( starts from index 0 ), there is no item(3) in your file.
Second, you should always check that you are able to find a reservation for that position before you are trying to remove it. In your case, I think you're trying to do .getParentNode() on a null element which is why you're seeing the NullPointer.
Element element = (Element)doc.getElementsByTagName("reservation").item(position);
if ( null != element) {
element.getParentNode().removeChild(element);
//etc
}
The objective is to read from a xml file and write to a new xml file while preserving newlines. We need the Document object to perform other xml tasks.
Say source.xml looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Code><![CDATA[code line1
code line 2
code line 3
code line 4]]></Code>
Now the destination should look the same with the newlines in the code element. But instead it ignores the newlines and makes it one line.
For writing, I am using the method below:
public static void writeFile(Document xml, File writeTo)
{
try
{
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
DOMSource source = new DOMSource(xml);
StreamResult result = new StreamResult(writeTo);
transformer.transform(source, result);
}
catch(TransformerException e)
{
System.out.println("Couldn't write file " + writeTo);
e.printStackTrace();
}
}
The Document xml is obtained using Parse(File) method in DocumentBuilder. Roughly in the lines of:
File file; // a list of files is recursively obtained from a given folder.
DocumentBuilderFactory documentBuilderfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = documentBuilderfactory.newDocumentBuilder();
Document xml = builder.parse(file);
The builder.parse seems to be losing the newlines in the CDATA of Code element.
How do we preserve the newlines?
I am new to Java APIs.
When I put your snippets together I get this program:
public class TestNewLine {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
DocumentBuilderFactory documentBuilderfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = documentBuilderfactory.newDocumentBuilder();
Document xml = builder.parse(TestNewLine.class.getResourceAsStream("data.xml"));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
DOMSource source = new DOMSource(xml);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
}
}
and it prints out:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Code><![CDATA[code line1
code line 2
code line 3
code line 4]]></Code>
As far as I understood, the newline is preserved already. What output did you expect?
I added the solution to the code below.
The code at the bottom is what I have. I removed the creation of all tags.
At the top in the xml file I get.<?xml version="1.0" encoding="UTF-8" standalone="no"?> Note that standalone is no, even thou I have it set to yes.
The first question: How do I get standalone = yes?
I would like to add <?xml-stylesheet type="text/xsl" href="my.stylesheet.xsl"?> at line two in the xml file.
Second question: How do I do that?
Some useful links? Anything?
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
doc.setXmlStandalone(true);
ProcessingInstruction pi = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"my.stylesheet.xsl\"");
Element root = doc.createElement("root-element");
doc.appendChild(root);
doc.insertBefore(pi, root);
<cut>
TransformerFactory transfac = TransformerFactory.newInstance();
transfac.setAttribute("indent-number", new Integer(2));
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
trans.setOutputProperty(OutputKeys.STANDALONE, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "name");
FileOutputStream fout = new FileOutputStream(filepath);
BufferedOutputStream bout= new BufferedOutputStream(fout);
trans.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(bout, "utf-8")));
I added
doc.setXmlStandalone(true);
ProcessingInstruction pi = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"my.stylesheet.xsl\"");`
before the cut and
doc.insertBefore(pi, root);
right after the root element was appended to the doc.
in my code, I wrote :
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
document.setXmlStandalone(true);
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer transformer = tfactory.newTransformer();
transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>