如何在XSLT 1中使用identity-transform将属性添加到由子元素条件限制的父节点?

时间:2013-08-06 11:14:47

标签: algorithm xslt

就像在this other question中一样,我很难用XSLT1表达简单的东西......

xsl:stylesheet我有这种“身份”转换,将属性align="center"添加到TD标记中,其他属性更多(必须留在那里)...触发器对于添加align,标记CENTER中存在标记TD。 (稍后将删除标记CENTER)。

<xsl:template match="@*|node()" name="identity">
  <xsl:copy>
    <xsl:if test="name()='td'  and .//center">
               <xsl:attribute name="align">center</xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template> 

此代码完成工作(xsl:if被忽略)。


需要td//center,而不仅td/center td/p/center。对于任何td//center,必须是通用的。输入示例:

<td colspan="2">
   <p><center>POF</center></p>
</td>

2 个答案:

答案 0 :(得分:3)

来自问题评论:

  

现在出现问题:<td align="x"><p><center>未更改,仅<td><p><center>

这是因为您使用

添加了align属性
<xsl:attribute name="align">center</xsl:attribute>

使用

复制现有的
<xsl:apply-templates select="@*|node()"/>

当你尝试向同一个元素添加两个具有相同名称的属性时,第二个添加的属性(在这种情况下是从input元素复制的那个)将获胜。

我肯定会将逻辑拆分为单独的模板:

<!-- copy everything as-is except for more specific templates below -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<!-- add align="center" to any td with a <center> descendant -->
<xsl:template match="td[.//center]">
  <td align="center">
    <!-- ignore any existing align attribute on the input td -->
    <xsl:apply-templates select="@*[local-name() != 'align'] | node()" />
  </td>
</xsl:template>

<!-- remove any <center> that's inside a td, but keep processing its children -->
<xsl:template match="td//center">
  <xsl:apply-templates />
</xsl:template>

这会改变

<td colspan="2" align="left">
   <p><center>POF</center></p>
</td>

<td align="center" colspan="2">
   <p>POF</p>
</td>

请注意,td[.//center] - td元素具有center元素后代 - 与td[//center]不同 - 发生在td元素中包含任何center元素的文档(不一定在td内)。

答案 1 :(得分:2)

使用以下输入XML:

<td colspan="2">
  <p>
    <center>POF</center>
  </p>
</td>

这个XSL样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*"/>

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

  <!-- Match any td elements with center descendants. -->
  <xsl:template match="td[.//center]">
    <xsl:copy>
      <!-- Add a new align attribute, then copy the original attributes and child nodes. -->
      <xsl:attribute name="align">center</xsl:attribute>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输出此XML:

<td align="center" colspan="2">
  <p>
    <center>POF</center>
  </p>
</td>

如果您想删除'center'元素,请添加以下模板:

<xsl:template match="center"/>