【问题标题】:How do I change the traversal order in dom4j? Is it possible at all?如何更改 dom4j 中的遍历顺序?有可能吗?
【发布时间】:2017-02-08 09:02:46
【问题描述】:

我正在尝试使用 dom4j 将元素添加到某些元素,但返回的选定节点列表不是我预期的顺序。添加的元素应充当计数器,以使用运行编号索引父元素。看看这段代码sn-p:

SAXReader reader = new SAXReader();
Document document = reader.read(new ByteArrayInputStream(fullString.getBytes(StandardCharsets.UTF_8)));
List<Node> filenameList = document.selectNodes("//ac:structured-macro[@ac:name='index-caption']/ac:rich-text-body/*[local-name()='p']/ac:image/ri:attachment/@ri:filename");
for (ListIterator<Node> iter = filenameList.listIterator(); iter.hasNext(); ) {
    Node n = iter.next();
    System.out.println(n.getText());
}

这是我最初的 xml “fullstring”(打印得很漂亮):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ac:confluence PUBLIC "-//Atlassian//Confluence 4 Page//EN" "http://www.atlassian.com/schema/confluence/4/confluence.dtd" [<!ENTITY clubs    "&#9827;">
<!ENTITY nbsp   "&#160;">
<!ENTITY ndash   "&#8211;">
<!ENTITY mdash   "&#8212;">]>
<ac:confluence xmlns:ac="http://www.atlassian.com/schema/confluence/4/ac/" xmlns:ri="http://www.atlassian.com/schema/confluence/4/ri/" xmlns="http://www.atlassian.com/schema/confluence/4/">
    <p>start</p>
    <ac:structured-macro ac:name="layout-boxes">
        <ac:parameter ac:name="layout">schritte</ac:parameter>
        <ac:parameter ac:name="title">First Level</ac:parameter>
        <ac:rich-text-body>
            <p>
                <ac:structured-macro ac:name="index-caption">
                    <ac:parameter ac:name="Prefix">Abb</ac:parameter>
                    <ac:parameter ac:name="Caption">Second Level</ac:parameter>
                    <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
                    <ac:rich-text-body>
                        <p>
                            <ac:image ac:height="250">
                                <ri:attachment ri:filename="rollinghills-2.jpg" />
                            </ac:image>
                        </p>
                    </ac:rich-text-body>
                </ac:structured-macro>
            </p>
            <ac:structured-macro ac:name="tip">
                <ac:parameter ac:name="title">Second Level</ac:parameter>
                <ac:rich-text-body>
                    <p>
                        <ac:structured-macro ac:name="index-caption">
                            <ac:parameter ac:name="Prefix">Abb</ac:parameter>
                            <ac:parameter ac:name="Caption">Third Level</ac:parameter>
                            <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
                            <ac:rich-text-body>
                                <p>
                                    <ac:image ac:height="250">
                                        <ri:attachment ri:filename="yosemite-13.jpg" />
                                    </ac:image>
                                </p>
                            </ac:rich-text-body>
                        </ac:structured-macro>
                    </p>
                </ac:rich-text-body>
            </ac:structured-macro>
        </ac:rich-text-body>
    </ac:structured-macro><p>
        <ac:structured-macro ac:name="index-caption">
            <ac:parameter ac:name="Prefix">Abb</ac:parameter>
            <ac:parameter ac:name="Caption">First Level</ac:parameter>
            <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
            <ac:rich-text-body>
                <p>
                    <ac:image ac:height="250">
                        <ri:attachment ri:filename="twinfalls.jpg" />
                    </ac:image>
                </p>
            </ac:rich-text-body>
        </ac:structured-macro>
    </p>
</ac:confluence>

我的预期顺序是:

  1. rollinghills-2.jpg
  2. yosemite-13.jpg
  3. twinfalls.jpg

如果我在在线 XPath 测试器中进行测试,我会得到预期的订单。

但是在 Java 中我得到了这个输出:

  1. twinfalls.jpg
  2. rollinghills-2.jpg
  3. yosemite-13.jpg

这些顺序的不同之处在于,按照我的预期顺序,dom4j/XPath 在到达下一个兄弟节点之前会尽可能深入地遍历。 dom4j/XPath 实际做的是:获取级别 1 的每个匹配,获取级别 2 的每个匹配,获取级别 3 的每个匹配...

如何更改遍历顺序?

最好的问候 Hasenchartbreaker

【问题讨论】:

    标签: java xml xpath dom4j


    【解决方案1】:

    编写我自己的 treeWalk 方法完成了这项工作:

    public void treeWalk(Document document) {
        treeWalk(document.getRootElement());
    }
    
    public void treeWalk(Element element) {
            System.out.println("abb: " + abb);
            if (element.getQualifiedName().equals("ac:structured-macro")
                    && element.attributeValue("name").equals("index-caption")) {
                Node filenameAttNode = element.selectSingleNode("./ac:rich-text-body/*[local-name()='p']/ac:image/ri:attachment/@ri:filename");
                System.out.println(filenameAttNode.getText());
    
            }
    
            for (int i = 0, size = element.nodeCount(); i < size; i++) {
                Node node = element.node(i);
                if (node instanceof Element) {
                    treeWalk((Element) node);
                } else {
                    // else
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      • 1970-01-01
      • 2020-07-16
      相关资源
      最近更新 更多