Foros aprenderaprogramar.com
Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: dardosmanai en 04 de Enero 2016, 21:02
-
Muy buenas.
Resulta que he hecho un programa que genera un XML a través de los objetos que hay escritos en un fichero, hasta ahi todo bien pero resulta que el XML me lo genera en una única linea es decir no tiene estructura de árbol.
Código Java
public static void crearXML()
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation implementation = builder.getDOMImplementation();
Document ficheroXML = implementation.createDocument(null, "departamentos", null); //El elemento Raiz del documento es departamentos
ficheroXML.setXmlVersion("1.0"); //asigno la version del XML
Element raiz = ficheroXML.getDocumentElement();
try
{
File fichero = new File("Departamentos.dat"); //Cargamos el fichero a leer
FileInputStream sacarAfichero = new FileInputStream(fichero); //Crea el flujo de Entrada
ObjectInputStream leer = new ObjectInputStream(sacarAfichero);
Departamento depart;
//Por cada vuelta del bucle leeo un departamento y genero su correspondiente XML
while((depart = (Departamento)leer.readObject()) != null)
{
Element departamento = ficheroXML.createElement("departamento"); //Creo una etiqueta departamento con para cada uno
Element nombreDepartamento = ficheroXML.createElement("nombreDepartamento"); //Cada departamento tiene una etiqueta nombreDepartamento
Text textoNombreDepartamento = ficheroXML.createTextNode(depart.get_nombre()); //Genero su texto a partir del objeto leido del fichero
nombreDepartamento.appendChild(textoNombreDepartamento); //Inserto el texto en la etiqueta nombreDepartamento
departamento.appendChild(nombreDepartamento); //Inserto la etiqueta nombreDepartamento en la etiqueta departamento
Element idDepartamento = ficheroXML.createElement("idDepartamento"); //Cada departamento tiene una etiqueta idDepartamento
Text textoIdDepartamento = ficheroXML.createTextNode(Integer.toString(depart.get_identificador())); //Genero su texto a partir del objeto leido del fichero
idDepartamento.appendChild(textoIdDepartamento); //Inserto el texto en la etiqueta idDepartamento
departamento.appendChild(idDepartamento); //Inserto la etiqueta idDepartamento en la etiqueta departamento
Element localidadDepartamento = ficheroXML.createElement("localidadDepartamento"); //Cada departamento tiene una etiqueta localidadDepartamento
Text textoLocalidadDepartamento = ficheroXML.createTextNode(depart.get_localidad()); //Genero su texto a partir del objeto leido del fichero
localidadDepartamento.appendChild(textoLocalidadDepartamento); //Inserto el texto en la etiqueta localidadDepartamento
departamento.appendChild(localidadDepartamento); //Inserto la etiqueta localidadDepartamento en la etiqueta departamento
raiz.appendChild(departamento);//Inserto la etiqueta departamento a la etiqueta departamentos
}
}
catch(Exception e)
{
ficheroXML.normalizeDocument(); //Esto no se si deberia generar la estructura de arbol
Source source = new DOMSource(ficheroXML);
Result result = new StreamResult(new java.io.File("departamentos.xml"));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
}
}
catch(Exception e)
{
}
}
Y el resultado del XML es el siguiente:
Código XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><departamentos><departamento><nombreDepartamento>Marketing</nombreDepartamento<idDepartamento>1</idDepartamento><localidadDepartamento>Madrid</localidadDepartamento></departamento><departamento><nombreDepartamento>Compras</nombreDepartamento><idDepartamento>2</idDepartamento><localidadDepartamento>Barcelona</localidadDepartamento></departamento><departamento><nombreDepartamento>Ventas</nombreDepartamento><idDepartamento>3</idDepartamento><localidadDepartamento>Bilbao</localidadDepartamento></departamento><departamento><nombreDepartamento>Finanzas</nombreDepartamento><idDepartamento>4</idDepartamento><localidadDepartamento>Sevilla</localidadDepartamento></departamento><departamento><nombreDepartamento>Investigación</nombreDepartamento><idDepartamento>5</idDepartamento><localidadDepartamento>León</localidadDepartamento></departamento><departamento><nombreDepartamento>I+D</nombreDepartamento><idDepartamento>6</idDepartamento><localidadDepartamento>Londres</localidadDepartamento></departamento></departamentos>
Esta todo en una linea y quiero que tenga la estructura:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<departamentos>
<departamento>
<nombreDepartamento>Marketing</nombreDepartamento>
<idDepartamento>1</idDepartamento>
<localidadDepartamento>Madrid</localidadDepartamento>
</departamento>
</departamentos>
No se como conseguirlo use el método normalizeDocument(); que yo creía que me lo dejaría con ese formato pero nada no consigo nada con el, también he intentado meter yo los saltos de linea pero no he conseguido hacerlo funcionar, alguien me podría decir como conseguir ese formato?
-
Hola, hay dos cuestiones diferentes. Que la salida del xml esté en una sola línea no significa que el xml no sea válido o esté mal configurado. De hecho si lo abres en un navegador te lo mostrará con un formateado correcto.
Ejemplo de código para crear un fichero xml:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.Transformer;
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;
import java.io.File;
public class CreateXmlFileDemo {
public static void main(String argv[]) {
try {
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder =
dbFactory.newDocumentBuilder();
Document doc = dBuilder.newDocument();
// root element
Element rootElement = doc.createElement("cars");
doc.appendChild(rootElement);
// supercars element
Element supercar = doc.createElement("supercars");
rootElement.appendChild(supercar);
// setting attribute to element
Attr attr = doc.createAttribute("company");
attr.setValue("Ferrari");
supercar.setAttributeNode(attr);
// carname element
Element carname = doc.createElement("carname");
Attr attrType = doc.createAttribute("type");
attrType.setValue("formula one");
carname.setAttributeNode(attrType);
carname.appendChild(
doc.createTextNode("Ferrari 101"));
supercar.appendChild(carname);
Element carname1 = doc.createElement("carname");
Attr attrType1 = doc.createAttribute("type");
attrType1.setValue("sports");
carname1.setAttributeNode(attrType1);
carname1.appendChild(
doc.createTextNode("Ferrari 202"));
supercar.appendChild(carname1);
// 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("C:\\cars.xml"));
transformer.transform(source, result);
// Output to console for testing
StreamResult consoleResult =
new StreamResult(System.out);
transformer.transform(source, consoleResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
El resultado si lo abres en un editor de texto está en una sola línea, si lo abres en un navegador lo verás en varias líneas.
Si quieres que el resultado se formatee adecuadamente puedes basarte en este código:
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
/**
* Pretty-prints xml, supplied as a string.
* <p/>
* eg.
* <code>
* String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>");
* </code>
*/
public class XmlFormatter {
public XmlFormatter() {
}
public String format(String unformattedXml) {
try {
final Document document = parseXmlFile(unformattedXml);
OutputFormat format = new OutputFormat(document);
format.setLineWidth(65);
format.setIndenting(true);
format.setIndent(2);
Writer out = new StringWriter();
XMLSerializer serializer = new XMLSerializer(out, format);
serializer.serialize(document);
return out.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Document parseXmlFile(String in) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(in));
return db.parse(is);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String unformattedXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +
" xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +
" xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +
" <Query>\n" +
" <query:CategorySchemeWhere>\n" +
" \t\t\t\t\t <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +
" </query:CategorySchemeWhere>\n" +
" </Query>\n\n\n\n\n" +
"</QueryMessage>";
System.out.println(new XmlFormatter().format(unformattedXml));
}
}
Saludos
-
Es cierto eso que dices que si lo ejecuto en el navegador aparece con el formato que yo quiero, pero si abro el archivo xml directamente no y creo que eso afecta si quiero leer el archivo xml desde java ya que solo tendría una fila o quizás no, por eso lo decía, soy inexperto en este tema y acostumbrado a ver unos xml bien formados eso me parecía raro.
La solución que me das la encontré ayer después de tanto buscar y preguntar en el foro funciona como yo quería en ese momento pero las clases: OutputFormat y XMLSerializer me dice que están obsoletas, pero si no es necesario hacer eso para trabajar con el xml pues perfecto.
Muchas Gracias.
-
Buenas, que el archivo tenga una fila o más de una fila es indiferente a efectos de utilizarlo en java o en cualquier otro lenguaje. La estructura del archivo debe ser correcta en cuanto a su estructura formal y apertura/cierre de etiquetas. Cumpliendo esto, no hay problema para su uso.
Salu2