2010-03-26 8 views
5

TAREA: Tengo un documento xml existente (UTF-8) que usa espacios de nombres xml y esquema xml. Necesito analizar un elemento en particular, anexar contenido (que también necesita usar prefijos de espacio de nombres xml) a este elemento y luego escribir de nuevo el documento.mejor analizador de Xml de Java para manipular/editar un documento xml existente

¿cuál es la mejor biblioteca de analizador de XML que debería utilizar para esta TAREA?

He visto un hilo anterior (Best XML parser for Java) pero no estaba seguro de si dom4j o JDOM es bueno para namespaces/xmlSchema y un buen soporte para los caracteres UTF-8.

Algunos programas de análisis que parece una tarea para
jdom
DOM4J
XOM
WoodStock

Alguna idea de cuál es el mejor? :-) Utilizo JDK 6 y prefiero NO usar las funciones SAX/DOM incorporadas para hacer este trabajo porque eso requiere que escriba demasiado código.

Ayudaría tener algunos ejemplos de hacer tal tarea.

+0

¿Cómo está haciendo eso con la incorporada en el centro de DOM va a ser demasiado para codificar? Ah, a la derecha - Java ... ;-) Pero en serio: ¿15-20 líneas es demasiado código en tu opinión? ¿Qué sería aceptable entonces? – Thomas

+0

La mejor biblioteca de procesamiento xml para tareas pesadas es vtd-xml, sin barras ... http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf –

Respuesta

5

Usando JDOM, teniendo un InputStream y convertirlo en un documento:

InputStream inputStream = (InputStream)httpURLConnection.getContent(); 
DocumentBuilderFactory docbf = DocumentBuilderFactory.newInstance(); 
docbf.setNamespaceAware(true); 
DocumentBuilder docbuilder = docbf.newDocumentBuilder(); 
Document document = docbuilder.parse(inputStream, baseUrl); 

En ese momento, usted tiene el XML en un objeto Java. Hecho. Fácil.

Puede usar el objeto del documento y la API de Java para simplemente recorrerlo, o también usar XPath, que me resulta más fácil (una vez que lo aprendí).

Construir un objeto XPath, que toma un poco:

public static XPath buildXPath() { 
    XPathFactory factory = XPathFactory.newInstance(); 
    XPath xpath = factory.newXPath(); 
    xpath.setNamespaceContext(new AtomNamespaceContext()); 
    return xpath; 
} 


public class AtomNamespaceContext implements NamespaceContext { 

    public String getNamespaceURI(String prefix) { 
     if (prefix == null) 
      throw new NullPointerException("Null prefix"); 
     else if ("a".equals(prefix)) 
      return "http://www.w3.org/2005/Atom"; 
     else if ("app".equals(prefix)) 
      return "http://www.w3.org/2007/app"; 
     else if ("os".equals(prefix)) 
      return "http://a9.com/-/spec/opensearch/1.1/"; 
     else if ("x".equals(prefix)) 
      return "http://www.w3.org/1999/xhtml"; 
     else if ("xml".equals(prefix)) 
      return XMLConstants.XML_NS_URI; 
     return XMLConstants.NULL_NS_URI; 
    } 

    // This method isn't necessary for XPath processing. 
    public String getPrefix(String uri) { 
     throw new UnsupportedOperationException(); 
    } 

    // This method isn't necessary for XPath processing either. 
    public Iterator getPrefixes(String uri) { 
     throw new UnsupportedOperationException(); 
    } 
} 

A continuación, sólo lo utilizan, que (afortunadamente) no toma mucho tiempo en absoluto:

return Integer.parseInt(xpath.evaluate("/a:feed/os:totalResults/text()", document)); 
+0

+1 - JDOM es la API más fácil de aprender para esto. XSLT será una mejor opción si tienes tareas como esta a menudo, sin embargo. – jsight

5

Usar XSLT. Seriamente. Este es un trabajo perfecto para eso. Solo use una plantilla de copia para copiar todo tal como está, a excepción del lugar donde necesita agregar más xml. Incluso puede agregar el XML al escribir XML en lugar de manipular el DOM.

Esta es la plantilla de copia:

<xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

Sé que mucha gente odia XSLT, pero esto es una tarea en la que sería realmente brillar y tener casi ningún código. Además, puedes usar lo que está en el JDK.

1

Parece que puede escribir una hoja de estilo xslt para hacer lo que quiera.

2

Desde escribir demasiado código es el principal problema para usted, es posible que desee considerar Joox:

http://code.google.com/p/joox/

He creado jOOX para ser un puerto de jQuery a Java. La tecnología subyacente es el DOM estándar de Java.Un código de ejemplo:

// Find the order at index for and add an element "paid" 
$(document).find("orders").children().eq(4) 
      .append("<paid>true</paid>"); 

// Find those orders that are paid and flag them as "settled" 
$(document).find("orders").children().find("paid") 
      .after("<settled>true</settled>"); 

// Add a complex element 
$(document).find("orders").append(
    $("order", $("date", "2011-08-14"), 
      $("amount", "155"), 
      $("paid", "false"), 
      $("settled", "false")).attr("id", "13"); 

Nota: Los espacios de nombres aún no se admiten explícitamente, pero se puede evitar que

+0

jOOX son buenas ideas. Pero perdí tiempo, porque esta tecnología no admite la manipulación con atributos. Sin él, esta tecnología solo es adecuada para la lectura. – wojand

+0

@wojand: ¿Qué te hace pensar eso? jOOX permite la manipulación de atributos. Vea el tercer ejemplo en mi respuesta, que establece 'id =" 13 "' –

+0

Mostrarme cómo agregar atributos a la etiqueta existente. Puede agregar una etiqueta, pero el problema es cuando necesita agregar atributos a la etiqueta existente. No pude encontrar una solución simple. No encontré ningún ejemplo en la página jOOX para este problema. Encima de su ejemplo, añada la etiqueta con el atributo, pero ¿cómo AÑADIR SOLO UN atributo a la etiqueta $ {} SIN? – wojand

Cuestiones relacionadas