与以下类似的xml文件集合:
<?xml version="1.0" encoding="UTF-8"?>
<title>xxxx</title>
<prolog>
<metadata>
<othermeta name="xxxx/>
<othermeta name="xxxx/>
</metadata>
</prolog>
<p>
Blah blah blah blah
</p>
(简体)
我想遍历每个文件,并将<prolog></prolog>
部分提取到一个输出文件中。
这是不工作:
<project name="export_metadata" default="all" basedir=".">
<target name="all" depends="extract"/>
<target name="extract">
<concat destFile="allMetadata.xml">
<fileset dir=".">
<include name="**/*.xml"/>
</fileset>
<filterchain>
<tokenfilter>
<replaceregex pattern="<.*?(<prolog>.*?</prolog>).*?/p>" replace="1" flags="gs" />
</tokenfilter>
</filterchain>
</concat>
</target>
</project>
它将每个文件的全部内容放入allMetadata.xml中,而不是序言部分。
我已经成功地使用了replaceregexp和捕获组一段时间了,但我认为我没有得到一些关于令牌过滤器如何工作的东西。
当我在regex101.com中尝试时,正则表达式和替换工作。这里的pattern
和replace
似乎应该匹配整个页面,在一个组中捕获序言部分,并用该组替换整个页面,然后输出该页面。但运气不好。我做错了什么?
我最终采用了一种不同的方法(过滤只影响我想要的XML文件中的标签,见下文),但我刚刚看到了下面的答案,现在我知道为什么我原来的方法不起作用了,很高兴知道。
我现在这样做:
<target name="extract">
<concat destFile="allMetadata_Guide.xml">
<fileset dir=".">
<include name="**/*.dita"/>
</fileset>
<filterchain>
<linecontainsregexp>
<regexp pattern="<othermeta|<title>|content=""/>
</linecontainsregexp>
</filterchain>
</concat>
</target>
我想转换包含othermeta
,或title
,或content=
的行,所以现在可以工作了。
LineTokenizer是<tokenfilter>
的默认标记器。LineTokenizer每次传递一行给<replaceregex>
。你的正则表达式不能匹配多行模式。
使用FileTokenizer来确保对整个输入文件只调用一次<replaceregex>
:
<tokenfilter>
<filetokenizer/>
<replaceregex
pattern="<.*?(<prolog>.*?</prolog>).*?/p>"
replace="1" flags="gs" />
</tokenfilter>