【问题标题】:Velocity #foreach with XmlTool node list with text nodesVelocity #foreach 与 XmlTool 节点列表与文本节点
【发布时间】:2018-07-09 04:43:55
【问题描述】:

我正在尝试编写一个使用 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 children 上的 .text 方法也连接了兄弟姐妹的文本节点!
我想要的是单独访问每个叶子文本节点:

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

感谢任何提示。谢谢!

【问题讨论】:

    标签: java templates dom foreach velocity


    【解决方案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())。

    【讨论】:

    • 我使用了 XSLT,它比 Velocity 更适合这个用例。你的解决方案虽然有效,所以我会继续接受它。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 2017-08-14
    • 2017-11-11
    • 1970-01-01
    相关资源
    最近更新 更多