我有example.ftl
文件,内容如下。我想在给定标签(例如xpath
(例如:/data/userInformation/addressInfo/addressList/#list/address/City
)地址之前或之后动态添加标签。并希望替换标记名或内容。
如果我对该文件使用XML解析器,则会解析异常。
<#assign payload = xml['child::node()']>
<?xml version="1.0" encoding="UTF-8"?>
<data>
<userInformation>
<userId>${payload.user.id}</userId>
<userName>${payload.user.name}</userName>
<userLanguage>${payload.user.@language}</userLanguage>
<addressInfo>
<addressList>
<#list payload.addressList.address as addressItem>
<address Type="${addressItem.@Type}">
<addressLine1>${addressItem.StreetNumber}</addressLine1>
<addressLine2>${addressItem.StreetName}</addressLine2>
<StreetType>${addressItem.StreetType}</StreetType>
<City>${addressItem.City}</City>
<State>${addressItem.State}</State>
<ZipCode>${addressItem.Zip}</ZipCode>
</address>
</#list>
</addressList>
</addressInfo>
</userInformation>
</data>
当前,我正在尝试使用StringUtils.substringBetween(content, "<"+tagName+">", "</"+tagName+">")
来获取标签之间的特定内容。但是,这不能满足我的要求。
您能帮忙什么更好的选择吗?
答案 0 :(得分:1)
我认为对此没有任何好的选择。
XML解析器无法工作的原因是Freemarker模板语言(FTL)不是有效的XML。您也许可以将FTL转换为XML(例如,通过将<#...>
重写为XML注释。然后解析并转换XML,最后反转注释转换。
文本模式匹配/基于正则表达式的方法可能有效,但它很脆弱。例如,由于匹配错误的环境。问题在于使用模式匹配进行解析非常困难……对于实际问题。
最后一个选择是FreeMarker(及其解析器)是开源的,因此(理论上)您可以对其进行修改:
a。您可以在解析后和使用前在FreeMarker解析树上进行转换。
b。您甚至可以执行上述操作,然后将其解析为FTL。 (但据我所知,FreeMarker不包含解析器……因此您需要自己编写一个。)
使用Javacc来实现自己的FTL解析器/转换器/未解析器。 (您可以从现有语法开始;请参见https://github.com/apache/freemarker/blob/2.3-gae/src/main/javacc/FTL.jj。)
其中有4个是最干净的,尽管您将要开发和维护大量的自定义代码。
也许最好的方法是找到一种不必解决此问题的方法。