The following code
import java.io.File;
import java.io.FileReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
public class Demo {
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("out.xml"));
xsr.nextTag(); // Advance to statements element
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
t.transform(new StAXSource(xsr), new StreamResult("result.txt"));
}
}
}
produces some txt, and on the first line of it there are processing instructions (<?xml version="1.0">). Where do they come from and how to get rid of them? And how to manipulate them?
You can disable the creation of the xml declaration by setting the output properties on the transformer:
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
If you want to generate text files from the xml then you probably want to specify an XSLT source in the TransformerFactory.newInstance call and set the output properties in that XSLT.
The line <?xml version="1.0"?> is an xml declaration. According to the W3C XML Recommendation
XML documents SHOULD begin with an XML declaration which specifies the version of XML being used.
it is supposed to be there (albeit not mandatory).
Btw. in a strict technical sense it is not a processing instruction.
Edit: the encoding can be changed with:
t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
Related
Im trying to insert a comment with syntax version information before the first node of an xml document but for some reason it always gets appended after the last element. I cant use other libraries like XStream and such.
I have already tried to do this via the append and the insertBefore method but both of them yield the same result. Is it possible to do this just with the plain Document, Comment and Node or do I have to use a Transformer?
Document doc = XmlDocumentUtil.createDocument();
//Create root node
Node rootNode = doc.createElement(NODE_DATA_CONFIGURATION);
doc.appendChild(rootNode);
//Create syntax identification comment
Comment syntaxIdentification = doc.createComment(writeSyntaxIdentificationQE);
doc.insertBefore(syntaxIdentification, rootNode);
//Create revision information
Element modificationNumber = doc.createElement("modificationNumber");
modificationNumber.setTextContent(String.valueOf(configTable.getModificationNumber()));
rootNode.appendChild(modificationNumber);
Element modificationTime = doc.createElement("modificationTime");
modificationTime.setTextContent(configTable.getModificationTime());
rootNode.appendChild(modificationTime);
Element modifier = doc.createElement("modifier");
modifier.setTextContent(configTable.getModifier());
rootNode.appendChild(modifier);
for (...) {
... some data generation
}
What I get:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DataConfiguration>
<modificationNumber>2</modificationNumber>
<modificationTime>2019-07-25 07:42:28.804 +0200</modificationTime>
<modifier>testuser</modifier>
<someData idxFrom="4" idxTo="9"
signalName="1" signalOffset="273.15" signalTemplate="asdf" skip="Y"/>
</DataConfiguration>
<!--SyntaxIdentification: 1.0-->
What I need:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--SyntaxIdentification: 1.0-->
<DataConfiguration>
<modificationNumber>2</modificationNumber>
<modificationTime>2019-07-25 07:42:28.804 +0200</modificationTime>
<modifier>testuser</modifier>
<someData idxFrom="4" idxTo="9"
signalName="1" signalOffset="273.15" signalTemplate="asdf" skip="Y"/>
</DataConfiguration>
To me your code seems good overall. Seems like you are missing only text nodes.
Here is full working code.
package xml;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
public class XMLComment {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
// Create root node
Node rootNode = doc.createElement("DataConfiguration");
doc.appendChild(rootNode);
// Create syntax identification comment
Comment syntaxIdentification = doc.createComment("SyntaxIdentification: 1.0");
doc.insertBefore(syntaxIdentification, rootNode);
// Create modificationNumber
Node modificationNumber = doc.createElement("modificationNumber");
Text mnText = doc.createTextNode("123456");
modificationNumber.appendChild(mnText);
// Create modificationTime
Element modificationTime = doc.createElement("modificationTime");
Text mtText = doc.createTextNode("2019-07-25 07:42:28.804 +0200");
modificationTime.appendChild(mtText);
rootNode.appendChild(modificationNumber);
rootNode.appendChild(modificationTime);
printXML(doc);
}
private static void printXML(Document doc) throws TransformerException {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
// 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 will output, close to what exactly you are looking for.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--SyntaxIdentification: 1.0--><DataConfiguration>
<modificationNumber>123456</modificationNumber>
<modificationTime>2019-07-25 07:42:28.804 +0200</modificationTime>
</DataConfiguration>
Hope it helps.
I used JAXB to create a very complicated .xml file which I saved on the drive. I also manually made an .xsl file which is my template.
How do I now programmatically use the above two to create an html output file ?
I tried various things and maybe I'm just tired but I can't even successfully open the .xml file into a Document.
Does someone have a working example ? I would greatly appreciate it! Thanks :)
I tried various things, including the official code examples but I can't find a working example. Nothing but null pointer exceptions. :(
The smallest working example I can give you:
import java.io.File;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class UseXMLToHTML {
public static void main(String[] args) throws TransformerException {
StreamResult result = new StreamResult(new File("output.html"));
StreamSource source = new StreamSource(new File("input.xml"));
StreamSource xslt = new StreamSource(new File("transform.xslt"));
Transformer transformer = TransformerFactory.newInstance().newTransformer(xslt);
transformer.transform(source, result);
}
}
This would probably do the trick;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
public class TestMain {
public static void main(String[] args) throws IOException, URISyntaxException, TransformerException {
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("transform.xslt"));
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(new File("input.xml"));
transformer.transform(text, new StreamResult(new File("output.xml")));
}
}
Consider trying out stuff from these urls:
http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog
http://www.w3schools.com/xsl/tryxslt_result.asp?xmlfile=cdcatalog&xsltfile=cdcatalog
I'm in a part of an application where I have an access to the XmlStreamReader which is representing the XML file needed to be fully read into a String.
Is there a way to obtain the XML content without building another XmlStreamReader or using another stream on the file?
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
private String getOuterXml(XMLStreamReader xmlr) throws TransformerConfigurationException,
TransformerFactoryConfigurationError, TransformerException
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StringWriter stringWriter = new StringWriter();
transformer.transform(new StAXSource(xmlr), new StreamResult(stringWriter));
return stringWriter.toString();
}
Using Java DOM I'm trying to set an attribute for an element without the namespace before the attribute name.
So, what I need is:
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
If I try to set the attribute as following element1.setAttributeNS("http://www.myschema.com", "attr1", value); I get an empty xmlns tag and additionaly a xmlns with prefix like the following:
<element1 attr1="value" xmlns="" xmlns:ns3="http://www.myschema.com">foo</element1>
If I try to set the attribute as following element1.setAttribute("xmlns:attr1", value); I get a prefix (xmlns) before my attribute name as shown here:
<element1 xmlns:attr1="value">foo</element1>
As for further information I create my elements as following:
Element element = dom.createElementNS("http://www.myschema.com", elemName);
element.appendChild(dom.createCDATASection("foo");
xmlElement.appendChild(element);
Let's look at your desired output again:
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
In this document, the following statements are true:
documentObject and element1 are in the http://www.myschema.com namespace.
The attribute attr1 is not in any namespace.
While elements whose names are not prefixed are going to be in whatever default namespace is in effect, attributes whose names are not prefixed are not in any namespaces. See the spec:
Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.
So to obtain the output you desire, you should be able to just do:
element1.setAttribute("attr1", value);
Of course this all depends on the desired output being correct. If really attr1 must be in a namespace, then your desired output is incorrect.
Below code will produce output
<?xml version="1.0" encoding="UTF-8"?>
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
Java Code
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XMLTest {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element element = doc.createElementNS("http://www.myschema.com", "documentObject");
doc.appendChild(element);
Element element1 = doc.createElement("element1");
element.appendChild(element1);
element1.appendChild(doc.createTextNode("foo"));
Attr attr = doc.createAttribute("attr1");
attr.setValue("value");
element1.setAttributeNode(attr);
element.appendChild(element1);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("testfile.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
}
}
I would like to know how do I overwrite and existing element in Java using dom parser. for example, I have the file
I am trying to overwrite the element and replace it with the element
Thanks.
Algorithm is easy:
Read a file and parse it to XML document
Make any changes you want
Overwrite existing file with new content
See my example:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class DomProgram {
public static void main(String[] args) throws Exception {
File xmlFile = new File("C:\\test.xml");
Document document = readXmlDocument(xmlFile);
makeChanges(document);
Transformer transformer = createXmlTransformer();
overwriteXmlFile(xmlFile, document, transformer);
}
private static void overwriteXmlFile(File xmlFile, Document document,
Transformer transformer) throws FileNotFoundException,
TransformerException {
StreamResult result = new StreamResult(new PrintWriter(
new FileOutputStream(xmlFile, false)));
DOMSource source = new DOMSource(document);
transformer.transform(source, result);
}
private static Transformer createXmlTransformer() throws Exception {
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
return transformer;
}
private static void makeChanges(Document document) {
Element root = document.getDocumentElement();
root.setAttribute("test", "testvalue");
}
private static Document readXmlDocument(File xmlFile) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlFile);
return document;
}
}
Example XML file:
<note>
<to>Ebele</to>
<from>mykhaylo</from>
<heading>Reminder</heading>
<body>Read about problem before you ask ;)</body>
</note>
Also see:
Simple Java DOM XML Example
How To Read XML File In Java – (DOM Parser)