2008-08-28 14 views
94

Tengo un documento XML completo en una cadena y me gustaría un objeto Document. Google aparece todo tipo de basura. ¿Cuál es la solución más simple? (En Java 1.5)¿Cómo cargo un org.w3c.dom.Document desde XML en una cadena?

Solución Gracias a Matt McMinn, me he decidido por esta implementación. Tiene el nivel correcto de flexibilidad de entrada y granularidad de excepción para mí. (Es bueno saber si el error proviene de malformación XML - SAXException - o simplemente mala IO - IOException.)

public static org.w3c.dom.Document loadXMLFrom(String xml) 
    throws org.xml.sax.SAXException, java.io.IOException { 
    return loadXMLFrom(new java.io.ByteArrayInputStream(xml.getBytes())); 
} 

public static org.w3c.dom.Document loadXMLFrom(java.io.InputStream is) 
    throws org.xml.sax.SAXException, java.io.IOException { 
    javax.xml.parsers.DocumentBuilderFactory factory = 
     javax.xml.parsers.DocumentBuilderFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    javax.xml.parsers.DocumentBuilder builder = null; 
    try { 
     builder = factory.newDocumentBuilder(); 
    } 
    catch (javax.xml.parsers.ParserConfigurationException ex) { 
    } 
    org.w3c.dom.Document doc = builder.parse(is); 
    is.close(); 
    return doc; 
} 
+0

Sería bueno si se puede corregir la solución. El uso de String.getByptes y InputStream impone problemas i18n. Uno de mis amigos obtuvo el código de aquí como es, lo que está mal. Suerte que findbugs detectó el problema. La solución correcta provista por erickson es usar InputSource. –

Respuesta

71

Esto funciona para mí en Java 1.5 - Me desnudé excepciones específicas para facilitar la lectura.

import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.DocumentBuilder; 
import org.w3c.dom.Document; 
import java.io.ByteArrayInputStream; 

public Document loadXMLFromString(String xml) throws Exception 
{ 
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 

    factory.setNamespaceAware(true); 
    DocumentBuilder builder = factory.newDocumentBuilder(); 

    return builder.parse(new ByteArrayInputStream(xml.getBytes())); 
} 
+27

Como se señala en la respuesta de sylvarking, este código usa 'getBytes()' sin consideración para la codificación. – McDowell

+2

¿te refieres a la respuesta de Erickson? o tal vez renombró su perfil? – rogerdpack

+1

no debería estar lanzando 'return (Document) builder.parse (new ByteArrayInputStream (xml.getBytes()))' '?? –

132

Whoa there!

Existe un problema potencialmente grave con este código, ya que ignora la codificación de caracteres especificada en el String (que es UTF-8 de forma predeterminada). Cuando llama al String.getBytes(), la codificación predeterminada de la plataforma se utiliza para codificar caracteres Unicode en bytes. Entonces, el analizador sintáctico puede pensar que está obteniendo datos UTF-8 cuando de hecho está recibiendo EBCDIC o algo así; ¡no es bonito!

su lugar, utilice el método de análisis que toma un InputSource, que puede ser construido con un lector, de esta manera:

import java.io.StringReader; 
import org.xml.sax.InputSource; 
… 
     return builder.parse(new InputSource(new StringReader(xml))); 

puede no parecer una gran cosa, pero la ignorancia de los problemas de codificación de caracteres conduce a código insidioso de putrefacción similar a y2k.

+3

Una solución tan simple pero tan elusiva en Google. Gracias +1 – pat8719

+5

Ahora me doy cuenta de que no debería simplemente copiar y pegar la respuesta aceptada, sino más bien leerla. –

+1

¡Impresionante! Salvamos nuestras vidas en JDK8 con la siguiente configuración file.encoding = ISO-8859_1, javax.servlet.request.encoding = UTF-8 PS La respuesta etiquetada como correcta no nos funcionó – kosta5

9

Acabo de tener un problema similar, excepto que necesitaba un NodeList y no un documento, esto es lo que se me ocurrió. En su mayoría es la misma solución que antes, aumentada para obtener el elemento raíz como NodeList y utilizando la sugerencia de erickson de utilizar un InputSource en lugar de problemas de codificación de caracteres.

private String DOC_ROOT="root"; 
String xml=getXmlString(); 
Document xmlDoc=loadXMLFrom(xml); 
Element template=xmlDoc.getDocumentElement(); 
NodeList nodes=xmlDoc.getElementsByTagName(DOC_ROOT); 

public static Document loadXMLFrom(String xml) throws Exception { 
     InputSource is= new InputSource(new StringReader(xml)); 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     factory.setNamespaceAware(true); 
     DocumentBuilder builder = null; 
     builder = factory.newDocumentBuilder(); 
     Document doc = builder.parse(is); 
     return doc; 
    } 
1

para manipular XML en Java, que siempre tienden a utilizar la API del transformador:

import javax.xml.transform.Source; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMResult; 
import javax.xml.transform.stream.StreamSource; 

public static Document loadXMLFrom(String xml) throws TransformerException { 
    Source source = new StreamSource(new StringReader(xml)); 
    DOMResult result = new DOMResult(); 
    TransformerFactory.newInstance().newTransformer().transform(source , result); 
    return (Document) result.getNode(); 
} 
Cuestiones relacionadas