two strings localecompare example comparar java unit-testing junit xmlunit

strings - localecompare javascript



Compara dos cadenas XML que ignoran el orden de los elementos (7)

Mi respuesta original está desactualizada. Si tuviera que compilarlo de nuevo, usaría xmlunit 2 y xmlunit-matchers. Tenga en cuenta que para la unidad xml, un orden diferente siempre es ''similar'' y no igual.

@Test public void testXmlUnit() { String myControlXML = "<test><elem>a</elem><elem>b</elem></test>"; String expected = "<test><elem>b</elem><elem>a</elem></test>"; assertThat(myControlXML, isSimilarTo(expected) .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))); //In case you wan''t to ignore whitespaces add ignoreWhitespace().normalizeWhitespace() assertThat(myControlXML, isSimilarTo(expected) .ignoreWhitespace() .normalizeWhitespace() .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))); }

Si alguien todavía no quiere usar una implementación java pura aquí está. Esta implementación extrae el contenido de xml y compara la lista ignorando el orden.

public static Document loadXMLFromString(String xml) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); InputSource is = new InputSource(new StringReader(xml)); return builder.parse(is); } @Test public void test() throws Exception { Document doc = loadXMLFromString("<test>/n" + " <elem>b</elem>/n" + " <elem>a</elem>/n" + "</test>"); XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); XPathExpression expr = xpath.compile("//test//elem"); NodeList all = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); List<String> values = new ArrayList<>(); if (all != null && all.getLength() > 0) { for (int i = 0; i < all.getLength(); i++) { values.add(all.item(i).getTextContent()); } } Set<String> expected = new HashSet<>(Arrays.asList("a", "b")); assertThat("List equality without order", values, containsInAnyOrder(expected.toArray())); }

Apoyo tengo dos cadenas xml

<test> <elem>a</elem> <elem>b</elem> </test> <test> <elem>b</elem> <elem>a</elem> </test>

¿Cómo escribir una prueba que compara esas dos cadenas e ignora el orden de los elementos?

Quiero que la prueba sea lo más breve posible, no hay lugar para el análisis XML de 10 líneas, etc. Estoy buscando una aserción simple o un smt similar.

Tengo esto (que no funciona)

Diff diff = XMLUnit.compareXML(expectedString, actualString); XMLAssert.assertXMLEqual("meh", diff, true);


Para mí, también necesitaba agregar el método: checkForSimilar() en DiffBuilder . Sin él, la afirmación estaba en error al decir que la secuencia de los nodos no era la misma (la posición en la lista secundaria no era la misma)

Mi código era:

Diff diff = Diffbuilder.compare(Input.fromFile(control)) .withTest(Input.fromFile(test)) .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)) .checkForSimilar() .build()


Para xmlunit 2.0 (estaba buscando esto) ahora está hecho, usando DefaultNodeMatcher

Diff diff = Diffbuilder.compare(Input.fromFile(control)) .withTest(Input.fromFile(test)) .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)) .build()

Espero que esto ayude esto ayuda a otras personas a googlear


Solo como un ejemplo de cómo comparar elementos xml más complejos en función de la igualdad del name de atributo. Por ejemplo:

<request> <param name="foo" style="" type="xs:int"/> <param name="Cookie" path="cookie" style="header" type="xs:string" /> </request>

contra

<request> <param name="Cookie" path="cookie" style="header" type="xs:string" /> <param name="foo" style="query" type="xs:int"/> </request>

Con el siguiente calificador de elemento personalizado:

final Diff diff = XMLUnit.compareXML(controlXml, testXml); diff.overrideElementQualifier(new ElementNameAndTextQualifier() { @Override public boolean qualifyForComparison(final Element control, final Element test) { // this condition is copied from super.super class if (!(control != null && test != null && equalsNamespace(control, test) && getNonNamespacedNodeName(control).equals(getNonNamespacedNodeName(test)))) { return false; } // matching based on ''name'' attribute if (control.hasAttribute("name") && test.hasAttribute("name")) { if (control.getAttribute("name").equals(test.getAttribute("name"))) { return true; } } return false; } }); XMLAssert.assertXMLEqual(diff, true);


XMLUnit hará lo que desee, pero debe especificar el elementQualifier. Sin un elementQualifier especificado, solo comparará los nodos en la misma posición.

Para su ejemplo, quiere un ElementNameAndTextQualifer, esto considera un nodo similar si existe uno que coincida con el nombre del elemento y su valor de texto, algo como:

Diff diff = new Diff(control, toTest); // we don''t care about ordering diff.overrideElementQualifier(new ElementNameAndTextQualifier()); XMLAssert.assertXMLEqual(diff, true);

Puede leer más sobre esto aquí: http://xmlunit.sourceforge.net/userguide/html/ar01s03.html#ElementQualifier


Publicación cruzada desde Comparar XML ignorando orden de elementos secundarios

Esta noche tuve una necesidad similar y no pude encontrar algo que se ajustara a mis necesidades.

Mi solución fue ordenar los dos archivos XML que quería diferenciar, ordenándolos alfabéticamente por el nombre del elemento. Una vez que ambos estuvieran en un orden consistente, pude diferenciar los dos archivos ordenados usando una herramienta de visualización visual regular.

Si este enfoque le parece útil a cualquier otra persona, he compartido el script de Python que escribí para realizar la clasificación en http://dalelane.co.uk/blog/?p=3225


OPCIÓN 1
Si el código XML es simple, intente esto:

String testString = ... assertTrue(testString.matches("(?m)^<test>(//s*<elem>(a|b)</elem>//s*){2}</test>$"));


OPCION 2
Si el XML es más elaborado, cárguelo con un analizador XML y compare los nodos reales encontrados con los nodos de referencia.