2015-08-29 14 views
0

使用XML集合的部分文件与此类似:ANT CONCAT仅提取每个文件

<?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="&lt;.*?(&lt;prolog&gt;.*?&lt;/prolog&gt;).*?/p&gt;" replace="\1" flags="gs" /> 
     </tokenfilter> 
    </filterchain> 
    </concat> 

</target> 
</project> 

它把每个文件的全部内容复制到allMetadata.xml,而不是序言部分。

我已经使用replaceregexp并成功捕获组了一段时间了,但我想我没有得到关于tokenfilters如何在这里工作的信息。

当我在regex101.com中尝试正则表达式和替换时,正则表达式和替换工作。看来patternreplace这里应该匹配整个页面,捕获组中的prolog部分,并用该组替换整个页面,然后输出该页面。但没有运气。我究竟做错了什么?

UPDATE

我弄成这样做不同的方式(过滤只是影响到我想要的XML文件中的代码,请参见下文),但我只看到了下面的答案,现在我明白为什么我的原创的方法不起作用,很高兴知道。

我现在这样做,而不是:

<target name="extract"> 
<concat destFile="allMetadata_Guide.xml"> 
    <fileset dir="."> 
     <include name="**/*.dita"/> 
    </fileset> 
    <filterchain> 
    <linecontainsregexp> 
     <regexp pattern="&lt;othermeta|&lt;title&gt;|content=&quot;"/> 
    </linecontainsregexp> 
    </filterchain> 
</concat> 
</target> 

我想改造包含othermeta,或title,或content=,线条所以这个现在工作。

回答

0

LineTokenizer是<tokenfilter>的默认分词器。 LineTokenizer一次只传递一行到<replaceregex>。你的正则表达式不会匹配多行的模式。

使用FileTokenizer代替,以确保<replaceregex>对整个输入文件只被调用一次

<tokenfilter> 
    <filetokenizer/> 
    <replaceregex 
     pattern="&lt;.*?(&lt;prolog&gt;.*?&lt;/prolog&gt;).*?/p&gt;" 
     replace="\1" flags="gs" /> 
</tokenfilter>