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).
Related
I am using w3c DOM to write xml file.
when i used to create first child node no trouble occurs.
For the 2nd time if i'm appending a new node in pre existing file it creates unwanted new lines in previous nodes and the new lines kept increasing everytime when i used to insert new nodes.
Here is my code...
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new File("D:\\TestXml.xml"));
Element rootElement = doc.getDocumentElement();
Element supercar = doc.createElement("supercars");
rootElement.appendChild(supercar);
Element carname = doc.createElement("carname");
carname.appendChild(doc.createTextNode("Ferrari 103"));
supercar.appendChild(carname);
Element carname1 = doc.createElement("carname");
carname1.appendChild(doc.createTextNode("Ferrari 204"));
supercar.appendChild(carname1);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("D:\\TestXml.xml"));
transformer.transform(source, result);
And here is the Generated File.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<cars>
<supercars>
<carname>Ferrari 101</carname>
<carname>Ferrari 202</carname>
</supercars>
<supercars>
<carname>Ferrari 103</carname>
<carname>Ferrari 204</carname>
</supercars>
</cars>
The Code above is used to append the 2nd node for the 1'st time the generated file haves no extra new lines.
And if add 10 new nodes the file haves so many unnecessary new lines resulting in more than 300 lines.
Also the file size got increased.
I cannot able to come to a conclusion that why this is occurring.
The Problem occurring for every new node insertion.
Any suggestions will be really helpful.
Consider running the identity transform XSLT where its <xsl:strip-space> removes such line breaks and spaces between nodes. You can easily incorporate XSLT in your existing code:
XSLT (save below as .xsl file, copies entire document as is)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Java
import javax.xml.transform.stream.StreamSource;
...
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new File("D:\\TestXml.xml"));
Element rootElement = doc.getDocumentElement();
Element supercar = doc.createElement("supercars");
rootElement.appendChild(supercar);
Element carname = doc.createElement("carname");
carname.appendChild(doc.createTextNode("Ferrari 103"));
supercar.appendChild(carname);
Element carname1 = doc.createElement("carname");
carname1.appendChild(doc.createTextNode("Ferrari 204"));
supercar.appendChild(carname1);
Source xslt = new StreamSource(new File("C:\\Path\\To\\Style.xsl")); // LOAD STYLESHEET
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xslt); // APPLY XSLT
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("D:\\TestXml.xml"));
transformer.transform(source, result);
I have this XML file:
<items>
<item><name>nam1</name><price>30</price></item>
<item><name>nam2</name><price>30</price></item>
</items>
I'm interested in reading the first item element as an XML Node, using XMLEventReader. I have this code:
try (var reader = new FileReader("items.xml", StandardCharsets.UTF_8)) {
final XMLInputFactory xif = XMLInputFactory.newInstance();
final XMLEventReader xer = xif.createXMLEventReader(reader);
final TransformerFactory tf = TransformerFactory.newInstance();
final Transformer t = tf.newTransformer();
// Skip until just *after* the first opening <item> tag
for (XMLEvent event = xer.peek()
; !event.isStartElement() ||
!event.asStartElement().getName().getLocalPart().equals("item")
; event = xer.nextEvent()) {
}
final DOMResult result = new DOMResult();
t.transform(new StAXSource(xer), result);
final Node node = result.getNode();
}
In the code, I position the "cursor" just after the first <item> tag, then read the whole element.
It seems to work, except that when I pretty-print the resulting Node, the name of the first tag encountered during parsing (name) seems to be used for the tag name of the enclosing element as well:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<name>
<name>nam1</name>
<price>30</price>
</name>
I expected the name of the closing tag (item) to be used. Something like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<item>
<name>nam1</name>
<price>30</price>
</item>
Is there a way to get this second behavior, or to otherwise configure the tag name of the enclosing element?
One possible solution is to create a new Element with the desired tag and copy into it all the children of the parse result:
final DocumentBuilder builder = docFactory.newDocumentBuilder();
final Document newDocument = builder.newDocument();
final Document document = (Document) result.getNode();
final Element element = (Element) document.getFirstChild();
final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
final Element newElement = newDocument.createElement("item");
final NodeList childNodes = element.getChildNodes();
for (int i=0; i < childNodes.getLength(); i++) {
newElement.appendChild(newDocument.importNode(childNodes.item(i),true));
}
But it feels somewhat roundabout and inelegant.
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.
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
}
I've a xml document, which will be used as a template
<?xml version="1.0" encoding="UTF-8" standalone="no"?><entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><content type="application/xml"><m:properties><d:AccountEnabled>true</d:AccountEnabled><d:DisplayName>SampleAppTestj5</d:DisplayName><d:MailNickname>saTestj5</d:MailNickname><d:Password>Qwerty1234</d:Password><d:UserPrincipalName>saTestj5#identropy.us</d:UserPrincipalName></m:properties></content></entry>
I'm calling it in java using this code where payLoadXML.xml has the above content.
"InputStream is = getClass().getClassLoader().getResourceAsStream("/payLoadXML.xml");"
Now I'm trying to edit the tag values for example changing the from "saTestj5" to "saTestj6" and then converting this entire xml and storing it in xml. Can anyone tell me how can I achieve this? I was told this can be done by using "Node" is it possible?
Use jaxb or sax parsers convert into object by using getter method and change the object and convert back to xml
try this
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = null;
docBuilder = docFactory.newDocumentBuilder();
Document doc = null;
InputStream is = getClass().getClassLoader().getResourceAsStream("/payLoadXML.xml");
doc = docBuilder.parse(is);
Node staff = doc.getElementsByTagName("m:properties").item(0);
Text givenNameValue = doc.createTextNode("abc");
Element givenName = doc.createElement("d:GivenName");
givenName.appendChild(givenNameValue);
staff.appendChild(givenName);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = null;
transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);