在 XSLT 中指定这种处理通常比在命令式语言中更容易和简单(不需要 regEx)。
下面的 XSLT 转换可以直接使用,或者它可以给出如何用另一种语言实现相同算法的想法:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pAction" select="'delete'"/>
<xsl:param name="pN" select="277"/>
<xsl:param name="pU" select="'/de/english/plan_book/plan_and_book.aspx'"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ps">
<ps>
<xsl:apply-templates select=
"*[not($pAction = 'delete')]
|
*[$pAction = 'delete' and not(@n = $pN)]
"/>
<xsl:if test="$pAction = 'add' and not(p[@n = $pN])">
<p n="{$pN}" u="{$pU}"/>
</xsl:if>
</ps>
</xsl:template>
<xsl:template match="p">
<xsl:choose>
<xsl:when test="not(@n = $pN)">
<xsl:call-template name="identity"/>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not($pAction = 'delete')">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<ps>
<p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
<p n="277" u="/ae/english/plan_book/plan_and_book.aspx"/>
<p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>
产生了想要的正确结果:
<ps>
<p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
<p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>
当参数$pAction
更改为:
<xsl:param name="pAction" select="''add'"/>
那么转换的结果是相同的 XML 文档(不变)。
当参数为:
<xsl:param name="pAction" select="''add'"/>
XML文档是:
<ps>
<p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
<p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>
那么结果是:
<ps>
<p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
<p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
<p n="277" u="/de/english/plan_book/plan_and_book.aspx"/>
</ps>