I am trying to edit a specific key inside an XML file. The problem is that after the file is saved, the '<' and '>' characters are transformed in coded characters (respectively: "& lt;" and "& gt;").
XML File:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<system.web>
<httpRuntime targetFramework="X.X"/>
</system.web>
<connectionStrings>
<add connectionString="Data Source=XXXX;user Id=YYYYY;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/>
</connectionStrings>
</configuration>
I'm updating the value of the entire connectionStrings key:
package br.com.sedna.bitbucket.plugin.enviromentsetup.utils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
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.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ModifyXmlFile {
private File _inputFile;
private String _filePath;
private DocumentBuilderFactory _docFactory;
private DocumentBuilder _docBuilder;
private Document _doc;
private Node _xmlObject;
private String CONNECTION_STRINGS = "<add connectionString=\"Data Source=XXXX;user Id=%s;password=ZZZZZ;\" name=\"Entities\" providerName=\"Oracle.ManagedDataAccess.Client\"/>";
public ModifyXmlFile(String xmlPath){
try {
this._filePath = xmlPath;
this._inputFile = new File(this._filePath);
this._docFactory = DocumentBuilderFactory.newInstance();
this._docBuilder = _docFactory.newDocumentBuilder();
this._doc = _docBuilder.parse(_inputFile);
this._xmlObject = _doc.getFirstChild();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ModifyXmlFile setNodeValue(String nodeName, String nodeValue){
Node nodeNameObject = this._doc.getElementsByTagName(nodeName).item(0);
try {
// updating the value of connectionStrings key
nodeNameObject.setTextContent(String.format(CONNECTION_STRINGS, nodeValue));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer;
transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
DOMSource source = new DOMSource(this._doc);
StreamResult consoleResult = new StreamResult(new File(this._filePath));
transformer.transform(source, consoleResult);
System.out.println("Done");
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return this;
}
}
Running this class:
ModifyXmlFile xmlHelper = new ModifyXmlFile("C:\\Web.config");
xmlHelper.setNodeValue("connectionStrings", "NEWVALUE");
The result:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<system.web>
<httpRuntime targetFramework="X.X"/>
</system.web>
<connectionStrings><add connectionString="Data Source=XXXX;user Id=NEWVALUE;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/></connectionStrings>
</connectionStrings>
</configuration>
I have tried changing the encode type without success.
I have modified the setNodeValue method. The relevant part follows:
public ModifyXmlFile setElementAttributeValue(String nodeXPath, String attributeName, String newAttributeValue) throws XPathExpressionException{
try {
XPath xPath = XPathFactory.newInstance().newXPath();
Node node = (Node)xPath.evaluate(nodeXPath, _doc, XPathConstants.NODE);
node.getAttributes().getNamedItem(attributeName).setNodeValue(String.format(CONNECTION_STRINGS, newAttributeValue));
Calling this via
setElementAttributeValue("/configuration/connectionStrings/add", "connectionString", "NEWVALUE" );
changes the value of the attribute connectionString on the element add.
There are several problems in the original code:
the consoleResult is named confusingly - the StreamResult points to a file
the parameter nodeName actually stands for parent node of the element to be edited and this is indeed what is retrieved per this._doc.getElementsByTagName(nodeName).item(0) - at least when setNodeValue is called with "connectionStrings" for nodeName.
the name of the attribute to be edited is hard-wired into the code.
as T.J. Crowder mentioned, the setTextContent method the original code is calling is used to set text content, i.e. the text between >< of some element. It is neccessary to distinguish between elements, attributes and text content and be aware of the fact that these are not interchangeable. It is not possible to add new element by adding text content which looks like (is formatted like) an element.
Please note that the new code is not production ready as at the very least the handling of potential null values would need to be added, e.g. on the result of getNamedItem(attributeName).
Related
I'm creating an XML using DOM, I open the XML with explorer and it seems fine.
After that I created an XSL for it, add the reference to it programatically to the XML and boom, it works no longer.
I inspect the code in the browser and save the file as XML.
I open the XML with notepad++ and noticed the npp shows the XML file is encoded in "UCS-2 LE BOM" even though the XML header sais it's in "UTF-8", I don't know if this has to do with being saved from the browser or it's because of Java transformer.File encoding according to npp
Anyway, I change the file encoding in npp to "UTF-8", open it again and it works flawlessly.
I've tried changing the transformer's encoding property transformer.setOutputProperty("encoding", "ISO-8859-1") to different values but it will just change the XML header.
I googled around but I haven't found anything that's worked so far.
This is the code where the XML is created
package modelo;
import java.awt.Desktop;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
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.TransformerConfigurationException;
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;
import org.w3c.dom.Node;
public class DAOXML {
private static final String rutaUno = ".\\VerLibro.xml";
private static final String rutaListado = ".\\listado.xml";
public static boolean toXML(ArrayList<Libro> libros2) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final String rutaActual = libros2.size()>1?rutaListado:rutaUno;
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
doc.setDocumentURI(rutaActual);
doc.setXmlStandalone(true);
Element libros = doc.createElement("libros");
for(Libro l : libros2) {
Element libro = doc.createElement("libro");
Element isbn = doc.createElement("isbn");
isbn.setTextContent(l.getISBN());
libro.appendChild(isbn);
Element editorial = doc.createElement("editorial_apellidos");
editorial.setTextContent(l.getEditorial_apellidos());
libro.appendChild(editorial);
Element autor = doc.createElement("autor");
autor.setTextContent(l.getAutor());
libro.appendChild(autor);
Element categoria = doc.createElement("categoria");
categoria.setTextContent(l.getCategoria());
libro.appendChild(categoria);
Element titulo = doc.createElement("titulo");
titulo.setTextContent(l.getTitulo());
libro.appendChild(titulo);
Element ubicacion = doc.createElement("ubicacion");
ubicacion.setTextContent(l.getUbiacion());
libro.appendChild(ubicacion);
libros.appendChild(libro);
}
doc.appendChild(libros);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// transformer.setOutputProperty("encoding", "ISO-8859-1");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(rutaActual));
//result.setWriter(new PrintWriter(new File(rutaActual), "UTF-8"));
transformer.transform(source, result);
if(rutaActual == rutaUno) {
Node pi = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"VerLibro.xsl\"");
doc.insertBefore(pi, libros);
}
else {
Node pi = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"listado.xsl\"");
doc.insertBefore(pi, libros);
}
Desktop.getDesktop().open(new File(rutaActual));
return true;
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
Thanks in advance.
Try adding this line before you call transform():
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
I am looking for an element "storage.hostname" and modifying that element.
Here is my piece of code,
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
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.Node;
import org.xml.sax.SAXException;
public class testXML {
public static void main(String argv[]) throws TransformerException {
String filepath = "C:\\qautilsServer\\target\\";
String hostname = "psvrhc9";
update(filepath,hostname);
}
public static void update(String destDirectory, String hostname) throws TransformerException{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
File rexsterFile = new File(destDirectory + "\\titan-rexster-server-2.5.0\\config\\rexster.xml");
DocumentBuilder docBuilder = null;
try
{
docBuilder = docFactory.newDocumentBuilder();
}
catch (ParserConfigurationException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
Document doc = null;
try
{
doc = docBuilder.parse(rexsterFile);
}
catch (SAXException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Node nodes1 = doc.getElementsByTagName("storage.hostname").item(0);
nodes1.setTextContent(hostname);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(destDirectory + "\\config.xml");
transformer.transform(source, result);
}
}
I get the same error when i do the following
nodes1.getTextContent();
My XML looks like this:
<graph>
<graph-name>graph</graph-name>
<graph-type>com.thinkaurelius.titan.tinkerpop.rexster.TitanGraphConfiguration</graph-type>
<graph-read-only>true</graph-read-only>
<properties>
<storage.backend>hbase</storage.backend>
<ids.num-partitions>1</ids.num-partitions>
<storage.hbase.region-count>8</storage.hbase.region-count>
<cluster.max-partitions>32</cluster.max-partitions>
<storage.hostname>psvrhc1</storage.hostname>
<storage.hbase.table>ldmns:titan_db</storage.hbase.table>
<storage.hbase.skip-schema-check>false</storage.hbase.skip-schema-check>
<query.force-index>false</query.force-index>
</properties>
<extensions>
<allows>
<allow>tp:gremlin</allow>
</allows>
</extensions>
</graph>
I am getting following issue and i have no clue why is this error coming:
Exception in thread "main" java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredAttrImpl.setTextContent(Ljava/lang/String;)V
Note: I am running in jre7 and not jre8. The code seems to be working fine with jre8. Since, my project only supports jre7, i can't upgrade to jre8.
I even tried nodes1.setNodeValue(hostname);
but it didnt work.
Any help will be highly appreciated.
I notice you are having an AbstractMethodError.
Reference says:
Thrown when an application tries to call an abstract method. Normally, this error is caught by the compiler; this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled.
I fear you might have issues with your Apache Xerces library. Maybe your runtime is using an older version which does not implement Node#setTextContent(String) (since DOM level 3).
Previously I modified your code to create a minimal reproducible case. But in fact it worked fine. Also works when i read from filesystem your full XML in my Eclipse Java EE 4.5 fresh setup. Probably the code is irrelevant, but I keep it on display just in case.
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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.Node;
public class TestXML {
public static void main(String argv[]) throws TransformerException {
try {
String xml = "<graph>" + "<storage.hostname>psvrhc1</storage.hostname>" + "</graph>";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
Node nodes1 = doc.getElementsByTagName("storage.hostname").item(0);
nodes1.setTextContent("blah");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
Outputs:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><graph><storage.hostname>blah</storage.hostname></graph>
Hi all and thanks for your time and help.
Im trying to parse a xml file in the "res/raw" folder and passing the result to other class to work with it.
I'm stuck and cannot find any solution, Im trying to learn programming, so, the whole code may be wrong and I failed catastrophically from the beginning.
this is the parser, it get a document from the raw folder and return the parsed document.
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import android.app.Activity;
public class Pars extends Activity{
public Document doc(){
InputStream is = getResources().openRawResource(R.raw.talechap01);
Document docout = null;
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = domFactory.newDocumentBuilder();
docout = builder.parse(is);
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return docout;
}
}
this class get the parsed document and find some content using xpath and pass it in a return.
I can not pass the parsed document "docout" from the class "Pars"
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class Commanders {
public static String getStory(String spage) {
XPathExpression expr;
XPath xpath = XPathFactory.newInstance().newXPath();
Object result = null;
String num = spage;
String par = null;
Document doc = //Here I need the document parsed from the "Pars" class
try {
expr = xpath.compile("//decision"+num+"/p//text()");
result = expr.evaluate(doc, XPathConstants.NODESET);
}
catch (XPathExpressionException e) {
e.printStackTrace();
}
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
par = nodes.item(i).getNodeValue();
// System.out.println(par);
}
return par;
}
}
Here is an example from the xml.
I'm trying to get the content of "" depending of the "decisionXXX" number.
<talechap01>
<Start></Start>
<decision000 id="000">
<p> part 1 text</p>
<p> second row text</p>
<pick chs= "001" name= "go to decision001"/>
<pick chs= "002" name= "go to decision002"/>
</decision000>
<decision001 id="001">
<p>parte 2</p>
<pick chs = "002" name= "go to decision002"/>
<pick chs = "003" name= "go to decision003"/>
</decision001>
I'm doing something/all wrong?
Is there even possible to do?
Maybe I don't understand something, but it seems like attribute "id" is a decision number,
i mean next
decision000 id=000
If it's true then you can first find nodes which start with and then select by id
I can't check it now, but it should work, try next expression:
//*[starts-with(local-name(), 'decision')][#id='your_num_value']
You need to adjust the function signature of Commanders#getStory(java.lang.String) so it takes your extra doc argument. You can then execute your code like...
Pars pars = new Pars();
Document doc = pars.doc();
Commanders.getStory(doc, spage)
I have a problem in parsing xml files with xslt stylesheets
http://docs.oracle.com/javase/tutorial/jaxp/xslt/transformingXML.html
i changed a bit in the stylizer code to input more than one xml file
(( just to give you a good background ))
everything is working perfectly BUT the root is mutiplied !
this is my xsl code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:text>
</xsl:text>
<request campus="UQU" year="2013" term="second">
<xsl:for-each select="/SIS_REP070/LIST_G_STUDENT_ID/G_STUDENT_ID">
.
.
.
<xsl:for-each select="document('sis_rep413b_anon.xml')/MODULE1/LIST_G_STUDENT_ID/G_STUDENT_ID[STUDENT_ID=$varID]">
.
.
.
<xsl:for-each select="document('sis_rep814.xml')/SIS_REP814/LIST_DEGREE_PLANS/DEGREE_PLANS[EDITION1=57][TOTAL_HRS=160]/LIST_G_COURSE_LEVEL/G_COURSE_LEVEL/LIST_G_COURSE_CODE/G_COURSE_CODE">
.
.
.
</xsl:for-each>
</request>
</xsl:template>
</xsl:stylesheet>
As you can see i am implementing this stylesheet on several xmls
so the root is outputed x times ( x= xml input files )
this is what the output looks like :
<request campus="UQU" year="2013" term="second">
<student key="42701646">
<name first="فؤاد" last="خوج"/><MAX>0</MAX>
<acadArea abbv="CSandISG"><major code="143100"/></acadArea>
<updateCourseRequests commit="true">
<courseOffering1 subjectArea="RELg" courseNumber="16312012" priority="19981.921" credit="2"/>
</updateCourseRequests></student>
.
.
.
.
</request>
<request campus="UQU" year="2013" term="second"/>
<request campus="UQU" year="2013" term="second"/>
<request campus="UQU" year="2013" term="second"/>
The root "request" is printed three more times !:(
Because i entered four xml files
This is the command i wrote in the command prompt :
java Stylizer data/file1.xsl data/file1.xml data/file2.xml data/file3.xml data/file4.xml
THE ORIGINAL STYLIZER:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
// For write operation
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
public class Stylizer {
// Global value so it can be ref'd by the tree-adapter
static Document document;
public static void main(String[] argv) {
if (argv.length != 2) {
System.err.println("Usage: java Stylizer stylesheet xmlfile");
System.exit(1);
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setNamespaceAware(true);
//factory.setValidating(true);
try {
File stylesheet = new File(argv[0]);
File datafile = new File(argv[1]);
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(datafile);
// Use a Transformer for output
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = tFactory.newTransformer(stylesource);
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (TransformerConfigurationException tce) {
// Error generated by the parser
System.out.println("\n** Transformer Factory error");
System.out.println(" " + tce.getMessage());
// Use the contained exception, if any
Throwable x = tce;
if (tce.getException() != null) {
x = tce.getException();
}
x.printStackTrace();
} catch (TransformerException te) {
// Error generated by the parser
System.out.println("\n** Transformation error");
System.out.println(" " + te.getMessage());
// Use the contained exception, if any
Throwable x = te;
if (te.getException() != null) {
x = te.getException();
}
x.printStackTrace();
} catch (SAXException sxe) {
// Error generated by this application
// (or a parser-initialization error)
Exception x = sxe;
if (sxe.getException() != null) {
x = sxe.getException();
}
x.printStackTrace();
} catch (ParserConfigurationException pce) {
// Parser with specified options can't be built
pce.printStackTrace();
} catch (IOException ioe) {
// I/O error
ioe.printStackTrace();
}
} // main
}
AFTER MY MODIFICATION :
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
// For write operation
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
public class Stylizer {
public static void main(String[] argv) {
if (argv.length < 2) {
System.err.println("Usage: java Stylizer stylesheet xmlfile");
System.exit(1);
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//factory.setNamespaceAware(true);
//factory.setValidating(true);
try {
File stylesheet = new File(argv[0]);
File [] fileList = new File[argv.length];
for(int i=1 ; i<argv.length ; i++)
fileList[i] = new File(argv[i]);
String targetExtension = ".xml";
int extIndex = argv[0].lastIndexOf(".");
String ext = argv[0].substring(extIndex);
argv[0] = argv[0].substring(0, extIndex) + targetExtension;
File outputname = new File(argv[0]);
DocumentBuilder builder = factory.newDocumentBuilder();
Document [] document = new Document[argv.length];
for(int i=1 ; i<argv.length ; i++)
document[i] = builder.parse(fileList[i]);
// Use a Transformer for output
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = tFactory.newTransformer(stylesource);
DOMSource [] source = new DOMSource [argv.length];
for(int i=1 ; i<argv.length ; i++)
source[i] = new DOMSource(document[i]);
FileOutputStream outputStream = new FileOutputStream((File)outputname);
StreamResult result = new StreamResult(outputStream);
for(int i=1 ; i<argv.length ; i++)
transformer.transform(source[i], result);
} catch (TransformerConfigurationException tce) {
// Error generated by the parser
System.out.println("\n** Transformer Factory error");
System.out.println(" " + tce.getMessage());
// Use the contained exception, if any
Throwable x = tce;
if (tce.getException() != null) {
x = tce.getException();
}
x.printStackTrace();
} catch (TransformerException te) {
// Error generated by the parser
System.out.println("\n** Transformation error");
System.out.println(" " + te.getMessage());
// Use the contained exception, if any
Throwable x = te;
if (te.getException() != null) {
x = te.getException();
}
x.printStackTrace();
} catch (SAXException sxe) {
// Error generated by this application
// (or a parser-initialization error)
Exception x = sxe;
if (sxe.getException() != null) {
x = sxe.getException();
}
x.printStackTrace();
} catch (ParserConfigurationException pce) {
// Parser with specified options can't be built
pce.printStackTrace();
} catch (IOException ioe) {
// I/O error
ioe.printStackTrace();
}
} // main
}
You create a new file outputname by changing the name of the stylesheet file to end in .xml.
You use this file for a new FileOutputStream called outputStream.
Then you use this output stream for a new StreamResult called result.
Finally you transform each of your source XML files using the same result stream.
The transformer is doing as you have told it: it is transforming each DOM source independently and putting the results of each one in the same place.
It's not clear what you expect. Do you want the output combined into a single XML document somehow? If so then you must say how you want them combined.
Are you using four command-line XML files as well as the other two XML files that are in document calls in the XSLT stylesheet? Six XML files to be combined into one is an awful lot!
If you want four independent transforms then you will have to create four different output files and send the output of each transform to a different place.
I have a Document object in java and I want to save it, so I have this code:
TransformerFactory fabTransformador = TransformerFactory.newInstance();
Transformer transformador = fabTransformador.newTransformer();
Source origin = new DOMSource(documentoXML);
Result destino = new StreamResult(new java.io.File(nombrearchivo));
transformador.transform(origin, destino);
where "nombrearchivo" is the file name (file.xml) and documentoXMLis the Document object.
When I execute the code, I receive as output: ERROR: ''
I don't receive any exception, just the message ERROR: ''
The document is about 1,3 GB, I don't know it it is the problem, and in that case, is there another way to save the file?
I use the next imports:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
Your code looks fine, but for reference there's an alternative approach you can use for saving a DOM document:
import org.w3c.dom.ls.*;
import java.io.FileOutputStream;
DOMImplementationLS ls = (DOMImplementationLS)documentoXML.getImplementation();
LSSerializer ser = ls.createLSSerializer();
LSOutput out = ls.createLSOutput();
out.setEncoding("UTF-8");
FileOutputStream output = new FileOutputStream("output.xml");
try {
out.setByteStream(output);
ser.write(documentoXML, out);
} finally {
output.close();
}
Use following to determine exact reason:
try {
secure.generaTextoXML();
} catch (Trowable thr) {
thr.printStackTrace();
}
... or try Level.ERROR instead of Level.SEVERE for your logger:
try {
secure.generaTextoXML();
} catch (TransformerConfigurationException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.ERROR, null, ex);
} catch (TransformerException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.ERROR, null, ex);
}