ANT xsl,条件替换

时间:2014-05-02 09:51:03

标签: xml xslt ant

我有一个XML文件,我想替换特定用户的密码。使用ANT和xsl文件我想替换旧密码,即password1

xml文件

<connector-factory connector-name="JmsAdapter" location="eis/wljms/Src">
    <config-property name="username" value="username1"></config-property>
    <config-property name="password" value="password1"></config-property>
    <log>
      <file path="/var/log/logfile.log"></file>
    </log>
</connector-factory>
<connector-factory connector-name="JmsAdapter" location="eis/wljms/Src">
    <config-property name="username" value="username2"></config-property>
    <config-property name="password" value="password2"></config-property>
</connector-factory>
<connector-factory connector-name="JmsAdapter" location="eis/wljms/Src">
    <config-property name="username" value="username3"></config-property>
    <config-property name="password" value=""></config-property>
    <log>
      <file path="/var/log/logfile.log"></file>
    </log>
</connector-factory>

xsl文件

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:template>
   <xsl:template match="config-property/@value[. =  'username1']">
            <config-property name="username" value="username1"/>
            <config-property name="password" value="PASSWD_DBLINK"/>
        </xsl:template>
 </xsl:stylesheet>

构建xml

<target name="JmsAdapter">
   <property name="tmp.file" value="JmsServer-oc4j-ra.tmp"/>
   <xslt in="oc4j-ra.xml" out="${tmp.file}" style="JmsServer-oc4j-ra.xsl">
   <outputproperty name="method" value="xml"/>
   </xslt>
   <replaceregexp file="${tmp.file}" match="PASSWD_DBLINK" replace="${PASSWD_DBLINK}" byline="true"/>
   <xmltask outputter="simple" source="${tmp.file}" dest="${tmp.file}">
   <remove path="/oc4j-connector-factories/connector-factory/config-property/@value[.='username1']"/>
   <remove path="/oc4j-connector-factories/connector-factory/config-property/@name[.='password']"/>
   </xmltask>
   </target>

结果显然是,密码被更改为正确的值,但是因为这行

<remove path="/oc4j-connector-factories/connector-factory/config-property/@name[.='password']"/>

删除所有其他密码,这不是我想要的。如果没有此语句,密码条目将附加到文件中,我也不希望这样。

我的问题是如何仅在正确的路径中替换密码,例如value = username1,而不是其他地方。

1 个答案:

答案 0 :(得分:2)

您可以使用xmltask选项使用replace执行整个操作,并使用稍微更具体的XPath表达式:

<xmltask outputter="simple" source="${tmp.file}" dest="${tmp.file}">
  <replace withText="${PASSWD_DBLINK}"
     path="/oc4j-connector-factories/connector-factory[
              config-property[@name='username'][@value = 'username1']
           ]/config-property[@name='password']/@value"/>
</xmltask>

这里我使用connector-factory级别的谓词来仅选择用户名为“username1”的connector-factory,然后修改其密码属性。

或者使用XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <!-- to pass in the new password value from Ant -->
  <xsl:param name="newPassword" />

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <!-- replace the password value for username1 only -->
  <xsl:template match="connector-factory[
          config-property[@name = 'username'][@value =  'username1']
        ]/config-property[@name = 'password']/@value">
    <xsl:attribute name="value">
      <xsl:value-of select="$newPassword" />
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

并使用

从Ant调用它
<xslt in="oc4j-ra.xml" out="${tmp.file}" style="JmsServer-oc4j-ra.xsl">
  <param name="newPassword" expression="${PASSWD_DBLINK}"/>
</xslt>