1

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

无论如何在不更新xml文件的情况下执行xslt之前更改颜色同时保留其他样式属性?

预期结果:

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

1 回答 1

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>

二、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>
于 2012-10-11T20:56:12.437 回答