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.baz
returns所有节点。
为了规避这个问题,可以直接使用底层的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()
上循环)。
我正在尝试编写一个使用 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.baz
returns所有节点。
为了规避这个问题,可以直接使用底层的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()
上循环)。