在XSLT之前操作xsl属性

时间:2012-10-11 19:53:26

标签: html xslt

给定xsl文件来改变颜色

 <xsl:if test="!colorChanges()">
    <StaticLabel style="{StaticLabel/@style}">                                                                                                      
      <Caption>
    <xsl:value-of select="$StaticLabel/Caption"/>                               
      </Caption>                                                          
      <PreviewCaption>
         <xsl:value-of select="$StaticLabel/Caption"/>
       </PreviewCaption>                                                                                                                  
     </StaticLabel>
  </xsl:if>

给出这个xml数据

 <StaticLabel style="font-family:Arial;color:#000000;font-size:9pt">
    <Caption><![CDATA[FoodType]]></Caption>
    <Name><![CDATA[French]]></Name>
 </StaticLabel>
</xsl:if>

xslt

之后的当前结果
<StaticLabel style="font-family:Arial;color:#000000;font-size:9pt">                                                  
   <Caption>Food Type</Caption>                                                 
   <PreviewCaption>French</PreviewCaption>                                              
</StaticLabel>

在执行xslt而不更新xml文件之前,是否仍然 ONLY 更改颜色同时保留其他样式属性?

预期结果:

<StaticLabel style="font-family:Arial;color:#CCCCCC;font-size:9pt">                                                  
   <Caption>Food Type</Caption>                                                 
   <PreviewCaption>French</PreviewCaption>                                              
</StaticLabel>

可能的XSL解决方案

<xsl:if test="colorChanges()">
    <StaticLabel>       
      <xsl:attribute name="style">                                                        
        //other style attributes stay same and ONLY edit color 
    <xsl:text>color:#CCCCCC"</xsl:text>
  </xsl:attribute>                                                                                              
      <Caption>
    <xsl:value-of select="$StaticLabel/Caption"/>                               
      </Caption>                                                          
      <PreviewCaption>
         <xsl:value-of select="$StaticLabel/Caption"/>
       </PreviewCaption>                                                                                                                  
     </StaticLabel>
  </xsl:if>

1 个答案:

答案 0 :(得分:0)

<强>予。 XSLT 1.0解决方案:

通用转换

<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="pStyle" select="'font-size:12pt'"/>

 <xsl:variable name="vStyleName"
      select="concat(';',substring-before($pStyle, ':'),':')"/>

 <xsl:variable name="vCurrentStyleValue" select=
 "substring-before(substring-after(concat(';', /*/@style, ';'), $vStyleName),
                   ';')"/>

  <xsl:variable name="vCurrentStyle"
       select="concat($vStyleName,$vCurrentStyleValue)"/>
 <xsl:template match="node()|@*" name="identiy">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*/@style">
  <xsl:attribute name="style">
   <xsl:variable name="vprecStyles" select=
   "substring-before(concat(';',., $vCurrentStyle), $vCurrentStyle)"/>
   <xsl:value-of select="substring($vprecStyles, 2)"/>
   <xsl:if test="$vprecStyles">;</xsl:if>
   <xsl:value-of select="$pStyle"/>
   <xsl:value-of select="substring-after(concat(';',.), $vCurrentStyle)"/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<StaticLabel style="font-family:Arial;color:#000000;font-size:9pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

生成想要的正确结果

<StaticLabel style="font-family:Arial;color:#CCCCCC;font-size:9pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

当我们将$pStyle参数更改为

 <xsl:param name="pStyle" select="'font-family:Courier'"/>

然后再次产生想要的,正确的结果:

<StaticLabel style="font-family:Courier;color:#000000;font-size:9pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

如果我们将$pStyle参数更改为

 <xsl:param name="pStyle" select="'font-size:12pt'"/>

我们再次获得正确的结果

<StaticLabel style="font-family:Arial;color:#000000;font-size:12pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

最后,如果我们将$pStyle参数更改为:

 <xsl:param name="pStyle" select="'line-height:15pt'"/>

我们再次获得正确的,期望的结果

<StaticLabel style="font-family:Arial;color:#000000;font-size:9pt;line-height:15pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

这是非常防错的 - 观察

<StaticLabel style="font-family:Arial;background-color:#ffffff;color:#000000;font-size:9pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

我们再次将$pStyle参数设为:

 <xsl:param name="pStyle" select="'color:#CCCCCC'"/>

我们仍然得到正确的结果(不会被其他以“color”结尾的CSS属性混淆):

<StaticLabel style="font-family:Arial;background-color:#ffffff;color:#CCCCCC;font-size:9pt">
   <Caption>Food Type</Caption>
   <PreviewCaption>French</PreviewCaption>
</StaticLabel>

<强> II。 XSLT 2.0解决方案 - 更容易:

<xsl:stylesheet version="2.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="pStyle" select="'color:#CCCCCC'"/>

 <xsl:variable name="vStyleName" select=
                  "substring-before($pStyle, ':')"/>

 <xsl:variable name="vcurStyles"
      select="tokenize(/*/@style, ';')"/>

 <xsl:variable name="vnewStyles" select=
  "if($vcurStyles[substring-before(.,':') eq $vStyleName])
     then ($vcurStyles[substring-before(.,':') ne $vStyleName],
           $pStyle)
     else ($vcurStyles, $pStyle)
  "/>

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

 <xsl:template match="/*/@style">
  <xsl:attribute name="style" select="string-join($vnewStyles, ';')">
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>