XMLUnit Diff проверяет XPath, когда XML-документ содержит пространства имен

Я хотел бы сравнить 2 документа xml

d1.xml

<?xml version="1.0" encoding="UTF-8"?>
<test:process xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1 xsd/BPELProcess1.xsd" xmlns:test="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1">
    <test:input1>RAVI1</test:input1>
   <test:input2>RAVI2</test:input2>
</test:process>

d2.xml

<?xml version="1.0" encoding="UTF-8"?>
<test:process xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1 xsd/BPELProcess1.xsd" xmlns:test="http://xmlns.oracle.com/Application2/FileRead1/BPELProcess1">
    <test:input1>RAVI1</test:input1>
   <test:input2>RAVI2</test:input2>
</test:process>

Написал код Java для сравнения этих файлов XML со следующим кодом

 public static void main(String[] args) throws Exception {
              
       String sourceXml = new String(readAllBytes(get("c:\\temp\\d1.xml")));
       String targetXml = new String(readAllBytes(get("c:\\temp\\d2.xml")));
       
    XPathEngine engine = new JAXPXPathEngine(); 
    
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
            
        Document sourceDoc = Convert.toDocument(Input.fromString(sourceXml).build(), dbf);
       
        Document targetDoc = Convert.toDocument(Input.fromString(targetXml).build(), dbf);
        
        Diff myDiff = DiffBuilder.compare(sourceDoc).withTest(targetDoc)
                    .checkForSimilar()
                                 .checkForIdentical()
                    .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes))
                    .ignoreWhitespace() 
                    .withNamespaceContext(null)
                    .build();
   
        Iterator<Difference> iter = myDiff.getDifferences().iterator();
           int size = 0;
           while (iter.hasNext()) {
             
              Difference d1 =  iter.next();
               System.out.println(d1);
             
            System.out.println(d1.getComparison().getControlDetails().getXPath()  +" (SOURCE) -->  "+d1.getComparison().getControlDetails().getValue());
            System.out.println(d1.getComparison().getTestDetails().getXPath()  +" (TARGET) -->  "+d1.getComparison().getTestDetails().getValue());
              
               System.out.println();
               size++;
           }
    }
    

Это результат, я получаю

Ожидаемое текстовое значение «RAVI2», но было «RAVI3» — сравнение RAVI2 в /process[1]/input2[1]/text()[1] с RAVI3 в /process[1]/input2[1]/text()[ 1] (РАЗНЫЕ) /process[1]/input2[1]/text()[1] (ИСТОЧНИК) --> RAVI2 /process[1]/input2[1]/text()[1] (ЦЕЛЬ) - -> РАВИ3

Здесь Xpath не содержит пространств имен /process[1]/input1[1]/text()[1]. Я ожидаю, что это будет так,

/тест:процесс[1]/тест:ввод1[1]/текст()

В моем коде я пытаюсь использовать этот Xpath, и он не дает никаких результатов. Если XML не содержит пространств имен, это работает нормально.

Движок XPathEngine = новый JAXPXPathEngine();

Строковое значение = engine.evaluate(d1.getComparison().getTestDetails().getXPath(), Input.fromString(targetXml).build()); System.out.println("------------------ " +значение);


person RaviReddy    schedule 15.03.2017    source источник


Ответы (1)


Я не вижу RAVI3 ни в одном из ваших примеров.

В любом случае, если вам нужны XPath с префиксами пространства имен, вы должны указать NamespaceContext (на самом деле Map от префикса до uri), содержащий желаемое сопоставление. См. Javadocs для DiffBuilder.

person Stefan Bodewig    schedule 15.03.2017
comment
Я хотел бы выбрать любой случайный файл xml, поэтому я, возможно, не знаю пространств имен, которые использует файл xml. Есть ли способ получить все пространства имен, содержащиеся в файле xml. - person RaviReddy; 15.03.2017
comment
Я не знаю ничего проще, чем синтаксический анализ документа и проверка каждого Node на предмет его URI пространства имен. Обратите внимание, что у вас может быть несколько URI внутри документа с одним и тем же префиксом (в разных контекстах), а также один и тот же URI с разными префиксами, поэтому простое использование префиксов, используемых внутри документа, в целом не работает. Вот почему я решил, чтобы пользователь XMLUnit явно указывал сопоставление. Не помогло бы, если бы XMLUnit создал суррогатные префиксы ns1, ns2 ..., которые вы не знали бы, как сопоставить с реальными URI пространства имен. - person Stefan Bodewig; 15.03.2017