Velocity #foreach with XmlTool 带有文本节点的节点列表

Velocity #foreach with XmlTool node list with text nodes

我正在尝试编写一个使用 DOM 对象的 Velocity 模板。特别是我的依赖项是 Velocity 1.7 和 Velocity-tools 2.0。

按照文档,这就是我将 DOM 传递给模板引擎的方式:

XmlTool tool = new XmlTool().parse(xmlString);
VelocityContext context = new VelocityContext();
context.put("xml", tool);
...

假设这是我的原始 XML 文档:

<root>
    <foo>
        <bar>
            <baz>10</baz>
            <qux>NO</qux>
        </bar>
        <bar>
            <baz>20</baz>
            <qux>YES</qux>
        </bar>
        <bar>
            <baz>30</baz>
            <qux>NO</qux>
        </bar>
    </foo>
</root>

这是我的模板文件:

#if($xml.foo)
<document>
    #foreach($bar in $xml.foo)
    <repeatableElement>
        <aaa>$bar.baz.text</aaa>
        <bbb>$bar.qux.text</bbb>
    </repeatableElement>
    #end
</document>

现在我的问题是,如果我 运行 这个,输出如下:

<document>
    <repeatableElement>
        <aaa>102030</aaa>
        <bbb>NOYESNO</bbb>
    </repeatableElement>
    <repeatableElement>
        <aaa>102030</aaa>
        <bbb>NOYESNO</bbb>
    </repeatableElement>
    <repeatableElement>
        <aaa>102030</aaa>
        <bbb>NOYESNO</bbb>
    </repeatableElement>
</document>

如您所见,#foreach 循环为每个 $bar 对象正确打印了一个 repeatableElement。但是 $bar 子节点上的 .text 方法也连接兄弟姐妹的文本节点!
我想要的是单独访问每个叶文本节点:

<repeatableElement>
    <aaa>10</aaa>
    <bbb>NO</bbb>
</repeatableElement>
<repeatableElement>
    <aaa>20</aaa>
    <bbb>YES</bbb>
</repeatableElement>
...

如有任何提示,我们将不胜感激。谢谢!

这是 Tools 2.0 XmlTool 的已知问题,其 getter 调用 JDOM 方法 getPath() 而不是 getUniquePath()。所以$bar.bazreturns所有节点。

为了规避这个问题,可以直接使用底层的JDOM API:

#if($xml.foo)
<document>
    #foreach($bar in $xml.foo.children())
    <repeatableElement>
        <aaa>$bar.node().element('baz').text</aaa>
        <bbb>$bar.node().element('qux').text</bbb>
    </repeatableElement>
    #end
</document>
#end

(另请注意,您应该在 $xml.foo.children() 上循环)。