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

Xml 如何将属性附加到XSL中的当前值?,xml,xslt,Xml,Xslt,为了便于访问,我正在尝试通过XSL将HTML格式转换为CSS。我已经让它工作了,但前提是之前没有样式属性。如何向已经存在的样式标记添加属性?这是我在没有样式属性时将align=更改为style=“text align:的代码: <!-- /align --> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()" /> </

为了便于访问,我正在尝试通过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>

我猜发生此错误是因为我试图向已通过这些转换之一更改的元素添加另一个属性。

您可能需要做的是匹配父元素,而不是属性本身,然后使用任何现有属性的内容添加一个新的
样式
属性,即s,然后添加
align
属性

试试这个XSLT

<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>

;
注意,如果您使用的是XSLT2.0,您可以稍微简化模板

<xsl:template match="*[@align]">
<xsl:copy>
  <xsl:apply-templates select="@* except (@style, @align)" />
  <xsl:attribute name="style">
    <xsl:value-of select="@style" />
    <xsl:if test="@style and not(ends-with(@style, ';'))">;</xsl:if>
    <xsl:apply-templates select="@align" />
  </xsl:attribute>
  <xsl:apply-templates />
</xsl:copy>
</xsl:template>

;

> p>我会考虑使用模板(使用<代码>模式>代码>属性)。 这里有一个XSLT1.0示例(2.0+可以简化)

XML输入

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

XSLT1.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 align="center" width="100"/>
<test style="text-align: center;width: 100px;"/>


Fiddle:

谢谢!!!这就像一个符咒。但是,如果我在文件中添加两个以上,我会遇到一个错误:转换过程中出现问题:无法在包含元素的子元素之后创建属性节点(样式)。知道原因吗?@salsaverde-确保
xsl:attribute
都在
之前。(另一个
apply templates
可以,因为它只选择属性节点。)@DanielHaley这是不可能的,对吗?我这样做是为了多个属性,比如border、align、frameborder、width、height等。这意味着我需要多个
@salsaverde-是否可以用导致错误的新代码更新您的问题?这在附加所有属性方面确实有效,但它复制了当前的cont在style属性中输入ent,并以某种方式将src也放入其中。例如,我有
,转换结果是
@salsaverde-Oops。忘记了样式模式的默认匹配。请查看我的更新。谢谢!!!您刚刚让我不用在15000页的每一页上都将HTML格式更改为CSS格式。救命R.@ Salsaveld-你很受欢迎。请考虑点击我旁边的复选标记来回答我的问题。您好!下面是一个简短的问题。如果我在我的代码/小提琴中添加一个表,它会抛出一个错误。转换似乎没有到达嵌套元素。您知道为什么吗?我尝试过使用不同的模板匹配组合,但没有用。