有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Velocity#foreach,带XmlTool节点列表,带文本节点

我正在尝试编写一个使用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>
...

任何提示都将不胜感激。谢谢


共 (1) 个答案

  1. # 1 楼答案

    这是Tools 2.0 XmlTool的一个已知问题,其getter调用JDOM方法getPath(),而不是getUniquePath()。因此$bar.baz返回所有节点

    要避免此问题,可以直接使用底层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()上循环)