181

기본적으로 사용자 지정 메시지 형식을 XML 메시지로 변환하고 다른 쪽 끝으로 보내는 응용 프로그램의 자동화 된 테스트를 작성하려고합니다. 필자는 입출력 메시지 쌍이 많아서 입력 메시지를 보내고 다른 쪽 끝으로 XML 메시지를 수신해야합니다.

실제 출력을 예상 출력과 비교할 시간이 생기면 몇 가지 문제가 있습니다. 나의 첫 번째 생각은 기대하고 실제 메시지에 문자열 비교를하는 것이었다. 이 예제는 우리가 가지고있는 예제 데이터가 항상 일관되게 형식화되지는 않았으며 종종 XML 네임 스페이스에 사용되는 별칭이 다르기 때문에 작동하지 않습니다 (때로는 네임 스페이스가 전혀 사용되지 않는 경우도 있습니다).

두 문자열을 구문 분석 한 다음 각 요소를 살펴보고 직접 비교하면 너무 어렵지는 않지만 더 나은 방법이나 라이브러리를 활용할 수 있다는 느낌이 들게됩니다.

그래서, 아래로 삶아, 질문은 :

유효한 XML을 포함하고있는 두 개의 Java String이 주어 졌을 때 의미 론적으로 동등한 지 어떻게 결정할 것입니까? 차이점을 파악할 수있는 방법이 있다면 보너스 포인트가됩니다.

14 답변


182

XMLUnit의 일과 같음

예:

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
    assertXMLEquals(xml1, xml2);  // assertXMLEquals comes from XMLTestCase
  }
}


  • 예전에는 XMLUNit에 문제가 있었지만 XML API 버전에서는 지나치게 혼란스러워서 신뢰할만한 것으로 입증되지 않았습니다. XOM을 위해 버려진 이후로 꽤 오래되었습니다. 그렇기 때문에 XOM을 사용하지 못했을 수도 있습니다. - skaffman
  • 초보자가 XMLUnit을 사용하는 경우 기본적으로 myDiff.similar ()가 반환합니다.그릇된컨트롤과 테스트 문서가 들여 쓰기 / 개행이 다른 경우. myDiff.similar ()가 아니라 myDiff.identical ()에서이 동작을 예상했습니다. XMLUnit.setIgnoreWhitespace (true)를 포함하십시오. setUp 메서드를 사용하여 테스트 클래스의 모든 테스트에 대한 동작을 변경하거나 개별 테스트 메서드에서 사용하여 해당 테스트의 동작 만 변경할 수 있습니다. - Stew
  • XMLUnit으로 시작하는 여러분의 의견에 대해 @Stew 주셔서 감사 드리며 확실히이 문제에 직면했을 것입니다. +1 - Jay
  • 두 버전의 github에서 XMLUnit 2를 사용하여이 작업을 수행하려는 경우,이 예는 전체적으로 다시 작성되므로이 예는 SourceForge의 XMLUnit 1에 대한 것입니다. 또한, 소스 포지 페이지는 "Java 1.x 용 XMLUnit은 여전히 유지 될 것이다"라고 기술하고있다. - Yngvar Kristiansen
  • 메소드는에서와 같이 assertXMLEqual입니다.XMLAssert.java. - user2818782

34

다음은 표준 JDK 라이브러리를 사용하여 문서가 동일한 지 확인합니다.

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 File("file1.xml"));
doc1.normalizeDocument();

Document doc2 = db.parse(new File("file2.xml"));
doc2.normalizeDocument();

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

normalize ()는주기가 없음을 확인하기위한 것입니다 (기술적으로는 없습니다)

위의 코드는 공백을 유지하고 평가하기 때문에 요소 내에서 공백이 필요합니다. Java와 함께 제공되는 표준 XML 파서는 표준 버전을 제공하거나 이해할 수있는 기능을 설정할 수 없습니다xml:space이것이 문제가된다면 xerces와 같은 대체 XML 파서가 필요하거나 JDOM을 사용해야 할 수도 있습니다.


  • 이는 네임 스페이스가없는 XML 또는 "정규화 된" 네임 스페이스 접두사. 나는 하나의 XML이 < ns1 : a xmlns : ns1 = "ns" / > 다른 하나는 koppor
  • dbf.setIgnoringElementContentWhitespace (true)에는 < 루트 > 이름 < / root >이 예상되는 결과가 없습니다. < root >와 동일하지 않습니다. 이름 < / 이름 > 이 솔루션 (두 개의 공간이 채워짐)을 사용하지만 XMLUnit은이 경우 동일한 결과를 제공합니다 (JDK8) - Miklos Krivan
  • 나에게 문제가되는 줄 바꿈을 무시하지 않는다. - Flyout
  • setIgnoringElementContentWhitespace(false) - Archimedes Trajano

27

DOM을 정규 형식으로 변환하는 Canonicalizer 유틸리티가 있습니다.이 유틸리티를 사용하면 문자열을 비교하고 비교할 수 있습니다. 그러므로 공백의 비정형이나 속성 순서와 관계없이 정기적으로 예측 가능한 문서 비교를 할 수 있습니다.

이것은 특히 이클립스와 같이 시각적 인 문자열 비교기가있는 IDE에서 잘 작동합니다. 문서 간의 의미 차이를 시각적으로 표현할 수 있습니다.


19

최신 버전위해 XMLUnit두 개의 XML이 동일하다고 주장 할 수 있습니다. 또한XMLUnit.setIgnoreWhitespace()XMLUnit.setIgnoreAttributeOrder()문제의 경우 필요할 수 있습니다.

아래의 간단한 XML 단위 사용 예제 작업 코드를 참조하십시오.

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

}

Maven을 사용한다면, 이것을 Maven에 추가하십시오.pom.xml:

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


  • 이것은 정적 방법으로 비교할 필요가있는 사람들에게 적합합니다. - Andy B
  • 이것은 완벽한 해답입니다. 고맙습니다.하지만 존재하지 않는 노드는 무시해야합니다. 결과 출력에서 그러한 출력을보고 싶지 않기 때문에 : 자식 노드 "null"의 예상 된 존재. 하지만 ...... 그걸 어떻게 할 수 있니? 문안 인사. @acdcjunior - limonik
  • XMLUnit.setIgnoreAttributeOrder (true); 작동하지 않습니다. 일부 노드의 순서가 다른 경우 비교가 실패합니다. - Bevor
  • [업데이트]이 솔루션은 작동합니다.stackoverflow.com/questions/33695041/… - Bevor
  • " IgnoreAttributeOrder " 속성 순서를 무시하고 노드 순서를 무시하지 않는다는 것을 의미합니까? - acdcjunior

6

고마워, 이걸 확장해라, 이거 해봐.

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


  • 꽤 늦었지만,이 코드에는 버그가 있습니다. diffNodes ()에서 node2는 참조되지 않습니다. 두 번째 루프는 node1을 잘못 재사용합니다 (이 문제를 해결하기 위해 코드를 편집했습니다). 또한 1 제한이 있습니다. 하위지도가 키잉되기 때문에이 diff는 요소 이름이 고유하지 않은 경우, 즉 반복 가능한 하위 요소가 포함 된 요소를 지원하지 않습니다. - aberrant80

6

빌딩남자 이름의 대답은 XMLUnit v2를 사용한 예입니다.

이 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>

여기 테스트 코드가 있습니다.

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
    }
}

이 문서의 개요는 다음과 같습니다.https://github.com/xmlunit/xmlunit#comparing-two-documents


3

스카프맨이 좋은 대답을주는 것 같습니다.

또 다른 방법은 xmlstarlet 같은 commmand 라인 유틸리티를 사용하여 XML을 포맷하는 것입니다http://xmlstar.sourceforge.net/) 두 문자열을 모두 포맷 한 다음 diff 유틸리티 (라이브러리)를 사용하여 결과 출력 파일을 비교하십시오. 문제가 네임 스페이스에있을 때 이것이 좋은 해결책인지 나는 모른다.


2

나는 사용하고있다.Altova DiffDogXML 파일을 구조적으로 비교하는 옵션이 있습니다 (문자열 데이터 무시).

즉, '텍스트 무시'옵션을 선택하는 경우 다음을 의미합니다.

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

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

구조적으로 평등하다는 의미에서 동등하다. 데이터가 다르지만 구조가 아닌 예제 파일이 있으면 편리합니다!



1

전체 문자열 XML을 비교합니다 (도중에 형식을 다시 지정). IDE (IntelliJ, Eclipse)로 작업하기가 쉬워 졌으므로 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);
    }
}

나는 클라이언트 코드 (테스트 코드)가 더 깨끗하기 때문에 이것을 XmlUnit보다 선호한다.


  • 이것은 동일한 XML과 다른 XML을 사용하여 지금했던 두 가지 테스트에서 잘 작동합니다. IntelliJ diff를 사용하면 비교 된 XML의 차이점을 쉽게 찾아 낼 수 있습니다. - Yngvar Kristiansen
  • 그런데 Maven : < dependency >을 사용하는 경우이 종속성이 필요합니다. < groupId > org.apache.santuario < / groupId > < artifactId > xmlsec < / artifactId > < version > 2.0.6 < / version > < / dependency > - Yngvar Kristiansen

1

AssertJ1.4+는 XML 내용을 비교하기위한 특정 어설 션을 가지고 있습니다 :

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

여기에선적 서류 비치


1

아래의 코드는 저에게 효과적입니다.

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


0

Java 애플리케이션에서 JExamXML 사용하기

    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

나는 주된 질문에서 요구 된 것과 동일한 기능을 요구했다. 타사 라이브러리를 사용할 수 없기 때문에 @Archimedes Trajano 솔루션을 기반으로하는 자체 솔루션을 만들었습니다.

다음은 나의 해결책이다.

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

}

두 개의 XML 문자열을 비교하고 두 입력 문자열에서 고유 한 값으로 변환하여 불일치하는 네임 스페이스 매핑을 처리합니다.

즉 네임 스페이스를 변환 할 때 미세 조정할 수 있습니다. 하지만 제 요구 사항만으로도 효과가 있습니다.


-1

당신이 "의미 론적으로 동등하다"고 말한 이후로, xml 출력이 (문자열) 같음을 확인하는 것 이상을 원한다고 가정합니다.

< foo > 여기에 약간의 물건 < / foo > < / code >

< foo > 여기에 일부 물건 < / foo > < / code >

동등한 것으로 읽으십시오. 궁극적으로 메시지를 재구성하는 객체에 대해 "의미 상 동등한"것을 정의하는 방법이 중요 할 것입니다. 단순히 메시지에서 해당 객체를 빌드하고 사용자 정의 equals ()를 사용하여 원하는 것을 정의하십시오.


  • 대답이 아니라 질문입니다. - Kartoch

연결된 질문


관련된 질문

최근 질문