Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:比较XPath结构_Java_Xml_Xpath_Functional Testing - Fatal编程技术网

Java:比较XPath结构

Java:比较XPath结构,java,xml,xpath,functional-testing,Java,Xml,Xpath,Functional Testing,我正在编写一些功能测试,比较两个XML文档的XML结构。这意味着标记顺序和命名是重要的,而标记内容是无关的 例如,以下调用: 电话1: <?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De

我正在编写一些功能测试,比较两个XML文档的XML结构。这意味着标记顺序和命名是重要的,而标记内容是无关的

例如,以下调用:

电话1:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
  </book>
</bookstore>
电话2:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
  </book>
</bookstore>
具有相同的标记结构,但:

电话3:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="WEB">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
  </book>
</bookstore>
是不同的,因为它后面有一个标记,而调用1和2缺少该标记


比较XML结构的Java方法是什么?

您可以对这两个文档调用一个简单的XSLT转换,去掉所有文本节点和属性内容,然后对这两个结果调用XPath deep equal。

我编写了一个类,它将XML展平,并提供一个人类可读的字符串进行比较

为了进行比较,我创建了两个XPathFlatter对象,并比较它们的toString表示

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Node;

public class XPathFlattener {

    private Node root;

    public XPathFlattener(Node root) {
        this.root = root;
    }

    /**
     * Flattens a XPath tree to a list of nodes, in pre-order traversal.
     */
    public List<Node> flatten() {
        List<Node> nodes = flattenTreeToList(this.root, new ArrayList<Node>());
        return nodes; 
    }

    /**
     * Flattens a XPath tree to a list of Strings, each representing the name
     * of the node, but not its contents. 
     * The list is created using pre-order traversal.
     */
    @Override
    public String toString() {
        List<String> nodesStrings = new ArrayList<>();
        for (Node n:this.flatten()) {
            nodesStrings.add(stringRepresentation(n));
        }
        return StringUtils.join(nodesStrings, ", ");
    }

    /**
     * Recursively flattens a Node tree to a list, in pre-order traversal.
     * @param node
     * @param nodes
     * @return
     */
    private static List<Node> flattenTreeToList(Node node, List<Node> nodes) {
        nodes.add(node);
        for (int i=0; i< node.getChildNodes().getLength(); i++) {
            Node childNode = node.getChildNodes().item(i);
            flattenTreeToList(childNode, nodes);
        }
        return nodes;
    }

    /**
     * A String representation of the node structure, without its contents.
     * @param node
     * @return
     */
    private static String stringRepresentation(Node node) {
        return String.format("[%s, (type %d)]", node.getNodeName(), node.getNodeType());
    }

}

你所说的比较是什么意思?打印差异?打印差异会有好处,但即使打印第一个不同的节点也可以。我以前用Java做过XML比较过程,抱歉,无法共享代码。这不是小事。对于您所展示的结构,每个元素都可以使用一个相对简单的循环。我遇到的问题主要是性能,以及如何显示差异。如果你想要更一般的比较,那么你应该看看LCS算法:谢谢@rolfl,这是一条有用的信息。我不在乎性能,我也不需要一个别致的diff-like查看器。如果我找不到现成的解决方案,我可能只写一个并发布在Github上。你有针对这些XML的方案吗?可以帮助你很多。你能提供一个链接吗?一个Java代码示例将非常有用。我目前正在探索Apache Xalan,我不确定这是一条路。对不起,我在这里回答问题,要么是因为它们很有趣,要么是因为它们可以在几秒钟内得到回答,而这一个不属于这两个类别。我建议使用deep equal需要XSLT 2.0,Xalan不支持这一点;你想用撒克逊来做这个。