如何在XSL中将属性附加到当前值?

时间:2019-02-14 16:46:03

标签: xml xslt

我正尝试通过XSL将HTML格式转换为CSS,以实现可访问性。我有它的工作,但前提是以前没有样式属性。如何将属性添加到已经存在的样式标签中?这是我的代码,用于在没有样式属性时将align=更改为style="text-align:

<!-- /align -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@align">
<xsl:attribute name="style">
<xsl:value-of select="@style"/>
<xsl:attribute name="style" select="concat('text-align: ',.)"/>
</xsl:attribute>
</xsl:template>

我认为先前的属性将在concatting之前使用value-of包含在内,但它不起作用。我希望它能够添加text-align:,即使那里已经有样式标签,例如style="border: 1px; text-align:

编辑:

这是更新的代码,给我一个错误:

<!-- /align -->


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

    <xsl:template match="*[@align]">
        <xsl:copy>
            <xsl:apply-templates select="@*[not(local-name() = 'style' or local-name() = 'align')]" />
            <xsl:attribute name="style">
                <xsl:value-of select="@style" />
                <xsl:if test="@style and substring(@style, string-length(@style)) != ';'">; </xsl:if>
                <xsl:apply-templates select="@align" />
            </xsl:attribute>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@align">
        <xsl:value-of select="concat('text-align: ', .)"/>
    </xsl:template>

    <!-- /width -->

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

    <xsl:template match="*[@width]">
        <xsl:copy>
            <xsl:apply-templates select="@*[not(local-name() = 'style' or local-name() = 'width')]" />
            <xsl:attribute name="style">
                <xsl:value-of select="@style" />
                <xsl:if test="@style and substring(@style, string-length(@style)) != ';'">; </xsl:if>
                <xsl:apply-templates select="@width" />
            </xsl:attribute>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@width">
        <xsl:value-of select="concat('width: ', . , 'px')"/>
    </xsl:template>

我猜发生了这个错误,因为我正在尝试向已使用这些转换之一更改过的元素添加另一个属性。

2 个答案:

答案 0 :(得分:2)

您可能需要做的是匹配父元素,而不是属性本身,然后使用任何现有属性的内容添加新的style属性,然后附加{{1 }}属性。

尝试使用此XSLT

align

请注意,如果您使用的是XSLT 2.0,则可以稍微简化一下模板...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" indent="yes"/>

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

  <xsl:template match="*[@align]">
    <xsl:copy>
      <xsl:apply-templates select="@*[not(local-name() = 'style' or local-name() = 'align')]" />
      <xsl:attribute name="style">
        <xsl:value-of select="@style" />
        <xsl:if test="@style and substring(@style, string-length(@style)) != ';'">;</xsl:if>
        <xsl:apply-templates select="@align" />
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@align">
     <xsl:value-of select="concat('text-align: ', .)"/>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

我会考虑为属性使用模版模板(使用mode属性)。

这是一个XSLT 1.0示例(可以简化2.0 +)...

XML输入

<test align="center" width="100"/>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- This is the identity transform and is only needed once. -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[@align or @width]">
    <xsl:copy>
      <xsl:apply-templates select="@*[not(local-name()='style') and 
                                      not(local-name()='align') and 
                                      not(local-name()='width')]"/>
      <xsl:attribute name="style">
        <xsl:value-of select="@style" />
        <xsl:if test="@style and substring(@style, string-length(@style)) != ';'">; </xsl:if>
        <xsl:apply-templates select="@*" mode="style"/>
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@align" mode="style">
    <xsl:value-of select="concat('text-align: ', ., ';')"/>
  </xsl:template>

  <xsl:template match="@width" mode="style">
    <xsl:value-of select="concat('width: ', . , 'px', ';')"/>
  </xsl:template>

  <xsl:template match="@*" mode="style"/>

</xsl:stylesheet>

输出

<test style="text-align: center;width: 100px;"/>

提琴:http://xsltfiddle.liberty-development.net/bnnZVP/1