2010-03-26 11 views
5

COMPITO: Ho un documento xml esistente (UTF-8) che utilizza gli spazi dei nomi xml e lo schema xml. Ho bisogno di analizzare un particolare elemento, aggiungere il contenuto (che deve anche usare i prefissi dello spazio dei nomi xml) a questo elemento e quindi scrivere di nuovo il documento.miglior parser java Xml per manipolare/modificare un documento xml esistente

quale è la migliore libreria di parser XML che dovrei usare per questo TASK?

Ho visto un thread precedente (Best XML parser for Java) ma non ero sicuro se dom4j o JDOM siano utili per namespaces/xmlSchema e un buon supporto per i caratteri UTF-8.

Alcuni parser che sembra un compito per
JDOM
DOM4J
XOM
WoodStock

Ha idea di quale è il migliore? :-) Uso JDK 6 e preferirei NON utilizzare le funzioni SAX/DOM incorporate per fare questo lavoro, perché questo richiede di scrivere troppo codice.

Sarebbe utile avere alcuni esempi di tale compito.

+0

Come sta facendo che con il built-in struttura DOM sta per essere troppo di codice? Ah, giusto - Java ... ;-) Ma sul serio: 15-20 linee sono troppo codice secondo te? Cosa sarebbe accettabile allora? – Thomas

+0

La migliore lib di elaborazione xml per attività pesanti è vtd-xml, nessuna barra ... http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf –

risposta

5

Utilizzando JDOM, prendendo un InputStream e farne un documento:

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

A quel punto, si ha la XML in un oggetto Java. Fatto. Facile.

È possibile utilizzare l'oggetto documento e l'API Java per passarci sopra oppure utilizzare XPath, che trovo più semplice (una volta appresa).

costruire un oggetto XPath, che prende un po ':

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(); 
    } 
} 

Poi basta usarlo, che (per fortuna) non ci vuole molto tempo a tutti:

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

+1 - JDOM è l'API più semplice da imparare per questo. XSLT sarà una scelta migliore se hai spesso compiti come questi. – jsight

5

Utilizzare XSLT. Sul serio. Questo è un lavoro perfetto per questo. Basta usare un modello di copia per copiare tutto così com'è tranne per il posto in cui è necessario aggiungere più xml. È anche possibile aggiungere l'XML scrivendo effettivamente XML invece di manipolazione DOM.

Questo è il modello di copia:

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

Conosco un sacco di gente odia XSLT, ma questo è un compito dove sarebbe davvero brillare e prendere quasi nessun codice. Inoltre, puoi semplicemente usare quello che c'è nel JDK.

1

Sembra possibile scrivere un foglio di stile xslt per fare ciò che si desidera.

2

Dopo aver scritto troppo il codice è il problema principale per voi, si potrebbe prendere in considerazione Joox:

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

Ho creato jOOX per essere una porta di jQuery in Java. La tecnologia sottostante è il DOM standard di Java.Alcuni esempi di codice:

// 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: namespace non sono ancora esplicitamente supportati, ma è possibile lavorare intorno a quel

+0

jOOX è una buona idea. Ma ho perso tempo, perché questa tecnologia non supporta la manipolazione con gli attributi. Senza di essa, questa tecnologia è adatta solo per la lettura. – wojand

+0

@wojand: cosa ti fa pensare così? jOOX consente la manipolazione degli attributi. Vedi il terzo esempio nella mia risposta, che imposta 'id =" 13 "' –

+0

Mostrami come aggiungere attributi al tag esistente. È possibile aggiungere un tag, ma il problema è quando è necessario aggiungere attributi al tag esistente. Non sono riuscito a trovare una soluzione semplice. Non ho trovato alcun esempio sulla pagina jOOX per questo problema. Sopra il tuo esempio aggiungi tag con attributo, ma come APPENDERE SOLO UN attributo a $ {} WITHOUT tag? – wojand