【问题标题】:Ant: How to xml-escape property values when copying xml files with "filtering"Ant:如何在使用“过滤”复制 xml 文件时对属性值进行 xml 转义
【发布时间】:2014-05-12 20:56:15
【问题描述】:

这个问题最近出现了。我一直在使用 ant 并知道我可以“破解”这个问题,但想问:ant 是否为这个用例提供了一个优雅的解决方案?

问题

当我使用 ant 复制 xml 文件并使用“过滤”属性“填充值”时,如何使其自动转义 & 符号(和其他 xml '特殊字符')?

上下文

我们让安装人员/实施人员手动编辑所有各种应用程序服务器特定的配置文件,而不是让他们在应用程序的根目录中编辑“build.properties”文件。 Ant 将文件的预配置“源”版本复制到“目标”目录,同时从属性文件中填充值

1) Build.properties 有这个值:

JDBC_PASSWORD=smith&wesson

2) “源”配置文件有这个元素:

  <local-tx-datasource>
    ...
    <password>@JDBC_PASSWORD@</password>
    ...
  </local-tx-datasource>

3) Ant 复制“源”配置目录中的 xml 文件并使用“过滤”属性填充“JDBC_PASSWORD”(以及其他属性):

<copy todir="${appserver.home.dir}" filtering="yes">
   <fileset dir="${appserver.conf.dir}">
      <include name="**/*.xml"/>
   </fileset>
</copy>

4) 因为该属性有一个 & 符号,所以生成的“目标”xml 文件是无效的。 (“&”应该是“&”)

  <local-tx-datasource>
    ...
    <password>smith&wesson</password>
    ...
  </local-tx-datasource>

期望的结果

我想要这个而不是 4:

  <local-tx-datasource>
    ...
    <password>smith&amp;wesson</password>
    ...
  </local-tx-datasource>

附加

我需要担心整个“字符类型”,即小于、大于等,以及与号。

提前致谢

【问题讨论】:

  • 我也有同样的问题。你是怎么解决你的?您是否编写了自定义编码器?谢谢。

标签: xml ant


【解决方案1】:
 JDBC_PASSWORD=smith&amp;wesson

将导致:

 <local-tx-datasource>
  <password>smith&amp;wesson</password>
 </local-tx-datasource>

将被解析为:

 <local-tx-datasource>
  <password>smith&wesson</password>
 </local-tx-datasource>


JDBC_PASSWORD=smith&amp;amp;wesson

将导致:

 <local-tx-datasource>
  <password>smith&amp;amp;wesson</password>
 </local-tx-datasource>

将被解析为:

 <local-tx-datasource>
  <password>smith&amp;wesson</password>
 </local-tx-datasource>

类似:

less-than : &amp;lt;

greater-than : &amp;gt;

【讨论】:

    【解决方案2】:

    您可以使用 Ant-Contrib 任务 URLEncode(是的,标题上写着 Foreach,但这只是为了引发 热度 偏离轨道。)。

    您可以使用它来确保您通过 &lt;filterset/&gt; 传递给标记化 XML 文件的任何值格式正确。

    您必须为 Ant-Contrib 任务定义 &lt;taskdef/&gt; 并包含 Ant Contrib jar。

    【讨论】:

    • URL 编码不同于 XML 编码。这是正确的方向,我相信人们需要一个自定义编码器。
    【解决方案3】:

    如果您不替换属性值,则始终可以使用CDATA 部分来代替。 CDATA 中的 & 号、小于号等不需要进行实体转义。

    <local-tx-datasource>
      ...
      <password><![CDATA[@JDBC_PASSWORD@]]></password>
      ...
    </local-tx-datasource>
    

    【讨论】:

      【解决方案4】:

      将您的问题与another SO answer 放在一起可以得到您想要的。

      首先,转换属性值:

      <loadresource property="jdbc.password.escaped">
        <propertyresource name="jdbc.password"/>
        <filterchain>
          <tokenfilter>
            <replacestring from="&amp;" to="&amp;amp;"/><!-- note: double escape -->
          </tokenfilter>
        </filterchain>
      </loadresource>
      

      现在,使用更新后的属性值:

      <filter token="JDBC_PASSWORD" value="${jdbc.password.escaped}" />
      
      <copy todir="${appserver.home.dir}" filtering="yes">
      <fileset dir="${appserver.conf.dir}">
          <include name="**/*.xml"/>
        </fileset>
      </copy>
      

      您可能需要调整上述内容以适合您的实际属性名称等,但这应该会让您继续前进。

      【讨论】:

        猜你喜欢
        • 2011-08-05
        • 1970-01-01
        • 2014-07-08
        • 1970-01-01
        • 1970-01-01
        • 2010-11-24
        • 2013-04-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多