2010-11-29 19 views
27

Estoy tratando de desarrollar una función de exportación XML para dar a mis usuarios de la aplicación para exportar sus datos en un formato XML. Tengo esta característica lista y funcionando hasta que comenzó a fallar en algunos casos. Entonces me di cuenta de que era debido a algunos caracteres especiales que necesitan ser codificados. por ejemplo, los datos pueden contener & o! o% o 'o # etc. etc. y esto necesita ser escapado correctamente. Me preguntaba si hay una utilidad genérica disponible que pueda escapar a todos los caracteres especiales según la especificación XML. No pude encontrar nada en Google.Escapar carácter especial cuando se genera un XML en Java

¿Existe algo así como que ya existe? o ¿Hay alguna otra forma de hacerlo?

Aquí está el código que estoy utilizando para generar XML


Document xmldoc = new DocumentImpl(); 
Element root = xmldoc.createElement("Report"); 

Element name= xmldoc.createElement((exportData.getChartName() == null) ? "Report" : exportData.getChartName()); 
if (exportData.getExportDataList().size() > 0 
    && exportData.getExportDataList().get(0) instanceof Vector) { 
    // First row is the HEADER, i.e name 
    Vector name = exportData.getExportDataList().get(0); 
    for (int i = 1; i value = exportData.getExportDataList().get(i); 
     Element sub_root = xmldoc.createElement("Data"); 
     //I had to remove a for loop from here. StackOverflow description field would not take that. :(
      // Insert header row 
      Element node = xmldoc.createElementNS(null, replaceUnrecognizedChars(name.get(j))); 
      Node node_value = xmldoc.createTextNode(value.get(j)); 
      node.appendChild(node_value); 
      sub_root.appendChild(node); 
      chartName.appendChild(sub_root); 
     } 
    } 
} 
root.appendChild(name); 

// Prepare the DOM document for writing 
Source source = new DOMSource(root); 

// Prepare the output file 
Result result = new StreamResult(file); 

// Write the DOM document to the file 
Transformer xformer = TransformerFactory.newInstance().newTransformer(); 
xformer.transform(source, result);` 

XML de ejemplo:


<Data> 
    <TimeStamp>2010-08-31 00:00:00.0</TimeStamp> 
    <[Name that needs to be encoded]>0.0</[Name that needs to be encoded]> 
    <Group_Average>1860.0</Group_Average> 
</Data> 

Respuesta

46

Puede usar apache common lang library para escapar de una cadena.

org.apache.commons.lang.StringEscapeUtils 

String escapedXml = StringEscapeUtils.escapeXml("the data might contain & or ! or % or ' or # etc"); 

Pero lo que está buscando es una manera de convertir cualquier cadena en un valid XML tag name. Para los caracteres ASCII, el nombre de la etiqueta XML debe comenzar con uno de _: a-zA-Z seguido de cualquier número de caracteres en _: a-zA-Z0-9.-

Creo que no hay biblioteca para Haga esto por usted, por lo que debe implementar su propia función para convertir cualquier cadena para que coincida con este patrón o, alternativamente, convertirlo en un valor de attritbue.

<property name="no more need to be encoded, it should be handled by XML library">0.0</property> 
+0

Gracias. Este es práctico, pero el problema es que solo maneja < > "& 'Estoy buscando algo que sea más extenso. La cadena que quiero escapar se está usando como nombre de nodo. Ahora también he agregado una muestra XML en la pregunta –

+2

De acuerdo con W3C para XML estándar, existe un número limitado de caracteres que se pueden usar como etiqueta de elemento. Puede crear un nodo genérico y agregar su encabezado como valor de un atributo, por ejemplo, gigadot

+0

Aquí está la regla para el nombre de la etiqueta del elemento http://www.w3.org/TR/REC-xml/#NT-Name No incluye < >" & '. – gigadot

1
public class RssParser { 
int length; 
    URL url; 
URLConnection urlConn; 
NodeList nodeList; 
Document doc; 
Node node; 
Element firstEle; 
NodeList titleList; 
Element ele; 
NodeList txtEleList; 
String retVal, urlStrToParse, rootNodeName; 

public RssParser(String urlStrToParse, String rootNodeName){ 
    this.urlStrToParse = urlStrToParse; 
    this.rootNodeName = rootNodeName; 

    url=null; 
    urlConn=null; 
    nodeList=null; 
    doc=null; 
    node=null; 
    firstEle=null; 
    titleList=null; 
    ele=null; 
    txtEleList=null; 
    retVal=null; 
      doc = null; 
    try { 
     url = new URL(this.urlStrToParse); 
        // dis is path of url which v'll parse 
     urlConn = url.openConnection(); 

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 

     String s = isToString(urlConn.getInputStream()); 
     s = s.replace("&", "&amp;"); 
     StringBuilder sb = 
          new StringBuilder 
            ("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 
     sb.append("\n"+s); 
     System.out.println("STR: \n"+sb.toString()); 
     s = sb.toString(); 

     doc = db.parse(urlConn.getInputStream()); 
     nodeList = doc.getElementsByTagName(this.rootNodeName); 
     // dis is d first node which 
     // contains other inner element-nodes 
     length =nodeList.getLength(); 
     firstEle=doc.getDocumentElement(); 
    } 
    catch (ParserConfigurationException pce) { 
     System.out.println("Could not Parse XML: " + pce.getMessage()); 
    } 
    catch (SAXException se) { 
     System.out.println("Could not Parse XML: " + se.getMessage()); 
    } 
    catch (IOException ioe) { 
     System.out.println("Invalid XML: " + ioe.getMessage()); 
    } 
    catch(Exception e){ 
     System.out.println("Error: "+e.toString()); 
    } 
} 


public String isToString(InputStream in) throws IOException { 
    StringBuffer out = new StringBuffer(); 
    byte[] b = new byte[512]; 
    for (int i; (i = in.read(b)) != -1;) { 
     out.append(new String(b, 0, i)); 
    } 
    return out.toString(); 
} 

public String getVal(int i, String param){ 
    node =nodeList.item(i); 
    if(node.getNodeType() == Node.ELEMENT_NODE) 
    { 
     System.out.println("Param: "+param); 
     titleList = firstEle.getElementsByTagName(param); 
     if(firstEle.hasAttribute("id")) 
     System.out.println("hasAttrib----------------"); 
     else System.out.println("Has NOTNOT  NOT"); 
     System.out.println("titleList: "+titleList.toString()); 
    ele = (Element)titleList.item(i); 
    System.out.println("ele: "+ele); 
     txtEleList = ele.getChildNodes(); 
    retVal=(((Node)txtEleList.item(0)).getNodeValue()).toString(); 
    if (retVal == null) 
     return null; 
      System.out.println("retVal: "+retVal); 
    } 
return retVal; 
} 
} 
+0

en este código, he hecho una clase de analizador, cuyo constructor toma dos parámetros; El primero es un flujo de entrada desde donde leemos el archivo xml y el segundo es el primer nombre de nodo interno; luego el método isToStream se utiliza para recuperar la cadena de la secuencia de entrada, este método devuelve la cadena; en esta cadena devuelta he reemplazado un carácter especial "&" por "&" y he añadido la versión xml y la codificación al principio; –

Cuestiones relacionadas