Il modo migliore per confrontare 2 documenti XML in Java


198

Sto cercando di scrivere un test automatizzato di un'applicazione che fondamentalmente traduce un formato di messaggio personalizzato in un messaggio XML e lo invia dall'altra parte. Ho un buon set di coppie di messaggi di input / output, quindi tutto quello che devo fare è inviare i messaggi di input e ascoltare il messaggio XML che esce dall'altra parte.

Quando arriva il momento di confrontare l'output effettivo con l'output previsto, mi imbatto in alcuni problemi. Il mio primo pensiero è stato solo quello di fare confronti tra stringhe sui messaggi attesi e reali. Questo non funziona molto bene perché i dati di esempio che abbiamo non sono sempre formattati in modo coerente e spesso ci sono alias diversi usati per lo spazio dei nomi XML (e talvolta gli spazi dei nomi non sono affatto usati).

So di poter analizzare entrambe le stringhe e quindi esaminare ciascun elemento e confrontarle da solo e questo non sarebbe troppo difficile da fare, ma ho la sensazione che ci sia un modo migliore o una libreria che posso sfruttare.

Quindi, in sostanza, la domanda è:

Date due stringhe Java che contengono entrambe un XML valido, come faresti per determinare se sono semanticamente equivalenti? Punti bonus se hai un modo per determinare quali sono le differenze.

Risposte:


197

Sembra un lavoro per XMLUnit

Esempio:

public class SomeTest extends XMLTestCase {
  @Test
  public void test() {
    String xml1 = ...
    String xml2 = ...

    XMLUnit.setIgnoreWhitespace(true); // ignore whitespace differences

    // can also compare xml Documents, InputSources, Readers, Diffs
    assertXMLEqual(xml1, xml2);  // assertXMLEquals comes from XMLTestCase
  }
}

1
Ho avuto problemi con XMLUNit in passato, è stato iper-nervoso con le versioni dell'API XML e non si è dimostrato affidabile. È passato un po 'di tempo da quando l'ho abbandonato per XOM, quindi, forse, da allora è impegnato.
Skaffman,

63
Per i principianti di XMLUnit, notare che, per impostazione predefinita, myDiff.similar () restituirà false se i documenti di controllo e test differiscono per rientro / righe. Mi aspettavo questo comportamento da myDiff.identical () e non da myDiff.similar (). Includi XMLUnit.setIgnoreWhitespace (true); nel metodo setUp per modificare il comportamento di tutti i test nella classe di test oppure utilizzarlo in un metodo di test individuale per modificare il comportamento solo per quel test.
Spezzatino

1
@Stew grazie per il tuo commento, ho appena iniziato con XMLUnit e sono sicuro che avrei dovuto affrontare questo problema. +1
Jay,

2
Nel caso tu stia provando questo con XMLUnit 2 su github, la versione 2 è una riscrittura completa, quindi questo esempio è per XMLUnit 1 su SourceForge. Inoltre, la pagina sourceforge indica "XMLUnit per Java 1.x verrà comunque mantenuto".
Yngvar Kristiansen,

1
il metodo è assertXMLEqual come da XMLAssert.java .
user2818782

36

Di seguito verrà verificato se i documenti sono uguali utilizzando le librerie JDK standard.

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
dbf.setNamespaceAware (true);
dbf.setCoalescing (true);
dbf.setIgnoringElementContentWhitespace (true);
dbf.setIgnoringComments (true);
DocumentBuilder db = dbf.newDocumentBuilder ();

Documento doc1 = db.parse (nuovo file ("file1.xml"));
doc1.normalizeDocument ();

Documento doc2 = db.parse (nuovo file ("file2.xml"));
doc2.normalizeDocument ();

Assert.assertTrue (doc1.isEqualNode (doc2));

normalize () è lì per assicurarsi che non ci siano cicli (tecnicamente non ci sarebbero)

Il codice sopra richiede che gli spazi bianchi siano gli stessi all'interno degli elementi, perché lo conserva e lo valuta. Il parser XML standard fornito con Java non ti consente di impostare una funzione per fornire una versione canonica o capire xml:spacese questo sarà un problema, quindi potresti aver bisogno di un parser XML sostitutivo come xerces o utilizzare JDOM.


4
Funziona perfettamente con XML senza spazi dei nomi o con prefissi dello spazio dei nomi "normalizzati". Dubito che funzioni se un XML è <ns1: a xmlns: ns1 = "ns" /> e l'altro è <ns2: a xmlns: ns2 = "ns" />
koppor

dbf.setIgnoringElementContentWhitespace (true) non ha il risultato. Mi aspetto che il <root> nome </root> non sia uguale al <root> nome </name> con questa soluzione (riempita con due spazi) ma XMLUnit fornisce lo stesso risultato in questo caso (JDK8)
Miklos Krivan

Per me non ignora le interruzioni di riga, il che è un problema.
Flyout91

setIgnoringElementContentWhitespace(false)
Archimede Trajano,

28

Xom ha un'utilità Canonicalizer che trasforma i tuoi DOM in una forma regolare, che puoi quindi stringere e confrontare. Pertanto, indipendentemente dalle irregolarità degli spazi bianchi o dall'ordinamento degli attributi, è possibile ottenere confronti regolari e prevedibili dei documenti.

Funziona particolarmente bene con gli IDE che hanno comparatori di stringhe visive dedicati, come Eclipse. Ottieni una rappresentazione visiva delle differenze semantiche tra i documenti.


21

L'ultima versione di XMLUnit può aiutare il lavoro di affermazione di due XML uguali. Inoltre XMLUnit.setIgnoreWhitespace()e XMLUnit.setIgnoreAttributeOrder()potrebbe essere necessario per il caso in questione.

Vedi il codice di lavoro di un semplice esempio di utilizzo dell'Unità XML di seguito.

import org.custommonkey.xmlunit.DetailedDiff;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Assert;

public class TestXml {

    public static void main(String[] args) throws Exception {
        String result = "<abc             attr=\"value1\"                title=\"something\">            </abc>";
        // will be ok
        assertXMLEquals("<abc attr=\"value1\" title=\"something\"></abc>", result);
    }

    public static void assertXMLEquals(String expectedXML, String actualXML) throws Exception {
        XMLUnit.setIgnoreWhitespace(true);
        XMLUnit.setIgnoreAttributeOrder(true);

        DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expectedXML, actualXML));

        List<?> allDifferences = diff.getAllDifferences();
        Assert.assertEquals("Differences found: "+ diff.toString(), 0, allDifferences.size());
    }

}

Se usi Maven, aggiungi questo al tuo pom.xml:

<dependency>
    <groupId>xmlunit</groupId>
    <artifactId>xmlunit</artifactId>
    <version>1.4</version>
</dependency>

Questo è perfetto per le persone che hanno bisogno di confrontare da un metodo statico.
Andy B,

Questa è la risposta perfetta Grazie .. Comunque devo ignorare i nodi che non esistono. Dal momento che non voglio vedere nell'output del risultato un simile output: Presenza attesa del nodo figlio "null" ma era ...... Come posso farlo? Saluti. @acdcjunior
limonik

1
XMLUnit.setIgnoreAttributeOrder (true); non funziona. Se alcuni nodi hanno un ordine diverso, il confronto fallirà.
Bevor

[UPDATE] questa soluzione funziona: stackoverflow.com/questions/33695041/...
Bevor

Ti rendi conto che "IgnoreAttributeOrder" significa ignora l'ordine degli attributi e non ignora l'ordine dei nodi, giusto?
acdcjunior,

7

Grazie, l'ho esteso, prova questo ...

import java.io.ByteArrayInputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

public class XmlDiff 
{
    private boolean nodeTypeDiff = true;
    private boolean nodeValueDiff = true;

    public boolean diff( String xml1, String xml2, List<String> diffs ) throws Exception
    {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setCoalescing(true);
        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setIgnoringComments(true);
        DocumentBuilder db = dbf.newDocumentBuilder();


        Document doc1 = db.parse(new ByteArrayInputStream(xml1.getBytes()));
        Document doc2 = db.parse(new ByteArrayInputStream(xml2.getBytes()));

        doc1.normalizeDocument();
        doc2.normalizeDocument();

        return diff( doc1, doc2, diffs );

    }

    /**
     * Diff 2 nodes and put the diffs in the list 
     */
    public boolean diff( Node node1, Node node2, List<String> diffs ) throws Exception
    {
        if( diffNodeExists( node1, node2, diffs ) )
        {
            return true;
        }

        if( nodeTypeDiff )
        {
            diffNodeType(node1, node2, diffs );
        }

        if( nodeValueDiff )
        {
            diffNodeValue(node1, node2, diffs );
        }


        System.out.println(node1.getNodeName() + "/" + node2.getNodeName());

        diffAttributes( node1, node2, diffs );
        diffNodes( node1, node2, diffs );

        return diffs.size() > 0;
    }

    /**
     * Diff the nodes
     */
    public boolean diffNodes( Node node1, Node node2, List<String> diffs ) throws Exception
    {
        //Sort by Name
        Map<String,Node> children1 = new LinkedHashMap<String,Node>();      
        for( Node child1 = node1.getFirstChild(); child1 != null; child1 = child1.getNextSibling() )
        {
            children1.put( child1.getNodeName(), child1 );
        }

        //Sort by Name
        Map<String,Node> children2 = new LinkedHashMap<String,Node>();      
        for( Node child2 = node2.getFirstChild(); child2!= null; child2 = child2.getNextSibling() )
        {
            children2.put( child2.getNodeName(), child2 );
        }

        //Diff all the children1
        for( Node child1 : children1.values() )
        {
            Node child2 = children2.remove( child1.getNodeName() );
            diff( child1, child2, diffs );
        }

        //Diff all the children2 left over
        for( Node child2 : children2.values() )
        {
            Node child1 = children1.get( child2.getNodeName() );
            diff( child1, child2, diffs );
        }

        return diffs.size() > 0;
    }


    /**
     * Diff the nodes
     */
    public boolean diffAttributes( Node node1, Node node2, List<String> diffs ) throws Exception
    {        
        //Sort by Name
        NamedNodeMap nodeMap1 = node1.getAttributes();
        Map<String,Node> attributes1 = new LinkedHashMap<String,Node>();        
        for( int index = 0; nodeMap1 != null && index < nodeMap1.getLength(); index++ )
        {
            attributes1.put( nodeMap1.item(index).getNodeName(), nodeMap1.item(index) );
        }

        //Sort by Name
        NamedNodeMap nodeMap2 = node2.getAttributes();
        Map<String,Node> attributes2 = new LinkedHashMap<String,Node>();        
        for( int index = 0; nodeMap2 != null && index < nodeMap2.getLength(); index++ )
        {
            attributes2.put( nodeMap2.item(index).getNodeName(), nodeMap2.item(index) );

        }

        //Diff all the attributes1
        for( Node attribute1 : attributes1.values() )
        {
            Node attribute2 = attributes2.remove( attribute1.getNodeName() );
            diff( attribute1, attribute2, diffs );
        }

        //Diff all the attributes2 left over
        for( Node attribute2 : attributes2.values() )
        {
            Node attribute1 = attributes1.get( attribute2.getNodeName() );
            diff( attribute1, attribute2, diffs );
        }

        return diffs.size() > 0;
    }
    /**
     * Check that the nodes exist
     */
    public boolean diffNodeExists( Node node1, Node node2, List<String> diffs ) throws Exception
    {
        if( node1 == null && node2 == null )
        {
            diffs.add( getPath(node2) + ":node " + node1 + "!=" + node2 + "\n" );
            return true;
        }

        if( node1 == null && node2 != null )
        {
            diffs.add( getPath(node2) + ":node " + node1 + "!=" + node2.getNodeName() );
            return true;
        }

        if( node1 != null && node2 == null )
        {
            diffs.add( getPath(node1) + ":node " + node1.getNodeName() + "!=" + node2 );
            return true;
        }

        return false;
    }

    /**
     * Diff the Node Type
     */
    public boolean diffNodeType( Node node1, Node node2, List<String> diffs ) throws Exception
    {       
        if( node1.getNodeType() != node2.getNodeType() ) 
        {
            diffs.add( getPath(node1) + ":type " + node1.getNodeType() + "!=" + node2.getNodeType() );
            return true;
        }

        return false;
    }

    /**
     * Diff the Node Value
     */
    public boolean diffNodeValue( Node node1, Node node2, List<String> diffs ) throws Exception
    {       
        if( node1.getNodeValue() == null && node2.getNodeValue() == null )
        {
            return false;
        }

        if( node1.getNodeValue() == null && node2.getNodeValue() != null )
        {
            diffs.add( getPath(node1) + ":type " + node1 + "!=" + node2.getNodeValue() );
            return true;
        }

        if( node1.getNodeValue() != null && node2.getNodeValue() == null )
        {
            diffs.add( getPath(node1) + ":type " + node1.getNodeValue() + "!=" + node2 );
            return true;
        }

        if( !node1.getNodeValue().equals( node2.getNodeValue() ) )
        {
            diffs.add( getPath(node1) + ":type " + node1.getNodeValue() + "!=" + node2.getNodeValue() );
            return true;
        }

        return false;
    }


    /**
     * Get the node path
     */
    public String getPath( Node node )
    {
        StringBuilder path = new StringBuilder();

        do
        {           
            path.insert(0, node.getNodeName() );
            path.insert( 0, "/" );
        }
        while( ( node = node.getParentNode() ) != null );

        return path.toString();
    }
}

3
Abbastanza tardi, ma volevo solo notare che questo pezzo di codice ha un bug: In diffNodes (), il nodo2 non viene referenziato - il secondo ciclo riutilizza nodo1 in modo errato (ho modificato il codice per risolvere questo problema). Inoltre, ha 1 limitazione: a causa del modo in cui le mappe figlio sono codificate, questa diff non supporta il caso in cui i nomi degli elementi non sono univoci, ovvero elementi contenenti elementi figlio ripetibili.
Aberrant80,

7

Sulla base della risposta di Tom , ecco un esempio usando XMLUnit v2.

Usa queste dipendenze maven

    <dependency>
        <groupId>org.xmlunit</groupId>
        <artifactId>xmlunit-core</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.xmlunit</groupId>
        <artifactId>xmlunit-matchers</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>

..e ecco il codice di prova

import static org.junit.Assert.assertThat;
import static org.xmlunit.matchers.CompareMatcher.isIdenticalTo;
import org.xmlunit.builder.Input;
import org.xmlunit.input.WhitespaceStrippedSource;

public class SomeTest extends XMLTestCase {
    @Test
    public void test() {
        String result = "<root></root>";
        String expected = "<root>  </root>";

        // ignore whitespace differences
        // https://github.com/xmlunit/user-guide/wiki/Providing-Input-to-XMLUnit#whitespacestrippedsource
        assertThat(result, isIdenticalTo(new WhitespaceStrippedSource(Input.from(expected).build())));

        assertThat(result, isIdenticalTo(Input.from(expected).build())); // will fail due to whitespace differences
    }
}

La documentazione che lo delinea è https://github.com/xmlunit/xmlunit#comparing-two-documents


3

skaffman sembra dare una buona risposta.

un altro modo è probabilmente quello di formattare l'XML usando un'utility di linea commmand come xmlstarlet ( http://xmlstar.sourceforge.net/ ) e quindi formattare entrambe le stringhe e quindi utilizzare qualsiasi utility diff (libreria) per diff i file di output risultanti. Non so se questa è una buona soluzione quando i problemi riguardano gli spazi dei nomi.


3

AssertJ 1.4+ ha affermazioni specifiche per confrontare il contenuto XML:

String expectedXml = "<foo />";
String actualXml = "<bar />";
assertThat(actualXml).isXmlEqualTo(expectedXml);

Ecco la documentazione


2

Sto usando Altova DiffDog che ha opzioni per confrontare strutturalmente i file XML (ignorando i dati delle stringhe).

Ciò significa che (se si seleziona l'opzione 'ignora testo'):

<foo a="xxx" b="xxx">xxx</foo>

e

<foo b="yyy" a="yyy">yyy</foo> 

sono uguali nel senso che hanno uguaglianza strutturale. Questo è utile se hai file di esempio che differiscono nei dati, ma non nella struttura!


3
L'unico inconveniente è che non è gratuito (99 € per una licenza pro), con 30 giorni di prova.
Pimin Konstantin Kefaloukos,

2
Ho trovato solo l'utilità ( altova.com/diffdog/diff-merge-tool.html ); bello avere una biblioteca.
dma_k,

1

Questo confronterà gli XML di stringa completi (riformattandoli lungo la strada). Semplifica il lavoro con il tuo IDE (IntelliJ, Eclipse), perché fai semplicemente clic e vedi visivamente la differenza nei file XML.

import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.c14n.InvalidCanonicalizerException;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.IOException;
import java.io.StringReader;

import static org.apache.xml.security.Init.init;
import static org.junit.Assert.assertEquals;

public class XmlUtils {
    static {
        init();
    }

    public static String toCanonicalXml(String xml) throws InvalidCanonicalizerException, ParserConfigurationException, SAXException, CanonicalizationException, IOException {
        Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
        byte canonXmlBytes[] = canon.canonicalize(xml.getBytes());
        return new String(canonXmlBytes);
    }

    public static String prettyFormat(String input) throws TransformerException, ParserConfigurationException, IOException, SAXException, InstantiationException, IllegalAccessException, ClassNotFoundException {
        InputSource src = new InputSource(new StringReader(input));
        Element document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
        Boolean keepDeclaration = input.startsWith("<?xml");
        DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
        DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
        LSSerializer writer = impl.createLSSerializer();
        writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
        writer.getDomConfig().setParameter("xml-declaration", keepDeclaration);
        return writer.writeToString(document);
    }

    public static void assertXMLEqual(String expected, String actual) throws ParserConfigurationException, IOException, SAXException, CanonicalizationException, InvalidCanonicalizerException, TransformerException, IllegalAccessException, ClassNotFoundException, InstantiationException {
        String canonicalExpected = prettyFormat(toCanonicalXml(expected));
        String canonicalActual = prettyFormat(toCanonicalXml(actual));
        assertEquals(canonicalExpected, canonicalActual);
    }
}

Preferisco questo a XmlUnit perché il codice client (codice test) è più pulito.


1
Funziona bene in due test che ho fatto ora, con lo stesso XML e con XML diverso. Con IntelliJ diff le differenze nell'XML comparato sono facili da individuare.
Yngvar Kristiansen,

1
A proposito, avrai bisogno di questa dipendenza se usi Maven: <dipendenza> <gruppoId> org.apache.santuario </groupId> <artifactId> xmlsec </artifactId> <versione> 2.0.6 </versione> </ dipendenza>
Yngvar Kristiansen,

1

Di seguito il codice funziona per me

String xml1 = ...
String xml2 = ...
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreAttributeOrder(true);
XMLAssert.assertXMLEqual(actualxml, xmlInDb);

1
Qualche contesto? Riferimenti alla biblioteca?
Ben

0

Utilizzo di JExamXML con l'applicazione java

    import com.a7soft.examxml.ExamXML;
    import com.a7soft.examxml.Options;

       .................

       // Reads two XML files into two strings
       String s1 = readFile("orders1.xml");
       String s2 = readFile("orders.xml");

       // Loads options saved in a property file
       Options.loadOptions("options");

       // Compares two Strings representing XML entities
       System.out.println( ExamXML.compareXMLString( s1, s2 ) );

0

Ho richiesto la stessa funzionalità richiesta nella domanda principale. Poiché non mi è stato permesso di utilizzare librerie di terze parti, ho creato la mia soluzione basandomi sulla soluzione @Archimedes Trajano.

Di seguito è la mia soluzione.

import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.junit.Assert;
import org.w3c.dom.Document;

/**
 * Asserts for asserting XML strings.
 */
public final class AssertXml {

    private AssertXml() {
    }

    private static Pattern NAMESPACE_PATTERN = Pattern.compile("xmlns:(ns\\d+)=\"(.*?)\"");

    /**
     * Asserts that two XML are of identical content (namespace aliases are ignored).
     * 
     * @param expectedXml expected XML
     * @param actualXml actual XML
     * @throws Exception thrown if XML parsing fails
     */
    public static void assertEqualXmls(String expectedXml, String actualXml) throws Exception {
        // Find all namespace mappings
        Map<String, String> fullnamespace2newAlias = new HashMap<String, String>();
        generateNewAliasesForNamespacesFromXml(expectedXml, fullnamespace2newAlias);
        generateNewAliasesForNamespacesFromXml(actualXml, fullnamespace2newAlias);

        for (Entry<String, String> entry : fullnamespace2newAlias.entrySet()) {
            String newAlias = entry.getValue();
            String namespace = entry.getKey();
            Pattern nsReplacePattern = Pattern.compile("xmlns:(ns\\d+)=\"" + namespace + "\"");
            expectedXml = transletaNamespaceAliasesToNewAlias(expectedXml, newAlias, nsReplacePattern);
            actualXml = transletaNamespaceAliasesToNewAlias(actualXml, newAlias, nsReplacePattern);
        }

        // nomralize namespaces accoring to given mapping

        DocumentBuilder db = initDocumentParserFactory();

        Document expectedDocuemnt = db.parse(new ByteArrayInputStream(expectedXml.getBytes(Charset.forName("UTF-8"))));
        expectedDocuemnt.normalizeDocument();

        Document actualDocument = db.parse(new ByteArrayInputStream(actualXml.getBytes(Charset.forName("UTF-8"))));
        actualDocument.normalizeDocument();

        if (!expectedDocuemnt.isEqualNode(actualDocument)) {
            Assert.assertEquals(expectedXml, actualXml); //just to better visualize the diffeences i.e. in eclipse
        }
    }


    private static DocumentBuilder initDocumentParserFactory() throws ParserConfigurationException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(false);
        dbf.setCoalescing(true);
        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setIgnoringComments(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        return db;
    }

    private static String transletaNamespaceAliasesToNewAlias(String xml, String newAlias, Pattern namespacePattern) {
        Matcher nsMatcherExp = namespacePattern.matcher(xml);
        if (nsMatcherExp.find()) {
            xml = xml.replaceAll(nsMatcherExp.group(1) + "[:]", newAlias + ":");
            xml = xml.replaceAll(nsMatcherExp.group(1) + "=", newAlias + "=");
        }
        return xml;
    }

    private static void generateNewAliasesForNamespacesFromXml(String xml, Map<String, String> fullnamespace2newAlias) {
        Matcher nsMatcher = NAMESPACE_PATTERN.matcher(xml);
        while (nsMatcher.find()) {
            if (!fullnamespace2newAlias.containsKey(nsMatcher.group(2))) {
                fullnamespace2newAlias.put(nsMatcher.group(2), "nsTr" + (fullnamespace2newAlias.size() + 1));
            }
        }
    }

}

Confronta due stringhe XML e si occupa di qualsiasi corrispondenza dello spazio dei nomi non corrispondente traducendole in valori univoci in entrambe le stringhe di input.

Può essere ottimizzato, ad esempio in caso di traduzione di spazi dei nomi. Ma per le mie esigenze fa proprio il lavoro.


-2

Dal momento che dici "semanticamente equivalente" suppongo che tu voglia fare di più che semplicemente verificare che gli output xml siano (stringhe) uguali e che tu voglia qualcosa di simile

<foo> alcune cose qui </foo> </code>

e

<foo> alcune cose qui </foo> </code>

leggi come equivalente. Alla fine importerà come stai definendo "semanticamente equivalente" su qualsiasi oggetto da cui stai ricostituendo il messaggio. Crea semplicemente l'oggetto dai messaggi e usa un uguale a () per definire ciò che stai cercando.


4
Non una risposta ma una domanda.
Kartoch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.