代码之家  ›  专栏  ›  技术社区  ›  Omnia9

XSLT:基于文本替换所有href

  •  -1
  • Omnia9  · 技术社区  · 9 年前

    我需要替换kml文件中的Iconstyle href。我很难为以下内容编写正确的xslt:


    伪代码:

    选择InconStyle中的所有href 如果href|text()=“y”,则替换为“x”( 其中y和x是映射列表。 )

    然后再次输出整个文档以及更改。


    XML块示例:

    <Style id='sn_x_normal0'>
        <IconStyle>
            <color>FFFFFFFF</color>
            <scale>0.75</scale>
            **<Icon><href>/ge/icon1.gif</href></Icon>**
            <hotSpot x='0.5' y='0' xunits='fraction' yunits='fraction'/>
        </IconStyle>
        <LineStyle>
            <color>FFFFFFFF</color>
        </LineStyle>
        <PolyStyle>
            <color>FFFFFFFF</color>
        </PolyStyle>
        <ListStyle>
        </ListStyle>
    </Style>
    

    上述xml的预期输出:

    <Style id='sn_x_normal0'>
        <IconStyle>
            <color>FFFFFFFF</color>
            <scale>0.75</scale>
            **<Icon><href>/ge/icon2.gif</href></Icon>**
            <hotSpot x='0.5' y='0' xunits='fraction' yunits='fraction'/>
        </IconStyle>
        <LineStyle>
            <color>FFFFFFFF</color>
        </LineStyle>
        <PolyStyle>
            <color>FFFFFFFF</color>
        </PolyStyle>
        <ListStyle>
        </ListStyle>
    </Style>
    

    xslt尝试了:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    >
        <xsl:output method="xml" indent="yes"/>
    
      <xsl:template match="Document">
        <xsl:apply-templates/>
      </xsl:template>
    
      <xsl:template match="Icon">
        <xsl:variable name="newIcon">
          <xsl:call-template name="string-replace-all">
            <xsl:with-param name="text" select="href" />
            <xsl:with-param name="replace" select="icon1.gif" />
            <xsl:with-param name="by" select="icon2.gif" />
          </xsl:call-template>
        </xsl:variable>
        <xsl:for-each  select="Icon/href">
          <xsl:value-of select="."/>
        </xsl:for-each>
    
      </xsl:template>
    
    
      <xsl:template name="string-replace-all">
        <xsl:param name="text" />
        <xsl:param name="replace" />
        <xsl:param name="by" />
        <xsl:choose>
          <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)" />
            <xsl:value-of select="$by" />
            <xsl:call-template name="string-replace-all">
              <xsl:with-param name="text" select="substring-after($text,$replace)" />
              <xsl:with-param name="replace" select="$replace" />
              <xsl:with-param name="by" select="$by" />
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$text" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:template>
    
    </xsl:stylesheet>
    
    1 回复  |  直到 9 年前
        1
  •  2
  •   michael.hor257k    9 年前

    选择InconStyle中的所有href如果href|text()=“y”,则替换 带“x”

    这不完全是你的例子告诉我们的 “如果href|text() 包含 “y”。。。"

    无论如何,试着这样做:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Icon/href">
        <xsl:copy>
            <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text" select="." />
                <xsl:with-param name="replace" select="'icon1.gif'" />
                <xsl:with-param name="by" select="'icon2.gif'" />
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>
    
    
    <xsl:template name="string-replace-all">
        <xsl:param name="text" />
        <xsl:param name="replace" />
        <xsl:param name="by" />
        <xsl:choose>
          <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)" />
            <xsl:value-of select="$by" />
            <xsl:call-template name="string-replace-all">
              <xsl:with-param name="text" select="substring-after($text,$replace)" />
              <xsl:with-param name="replace" select="$replace" />
              <xsl:with-param name="by" select="$by" />
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$text" />
          </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    </xsl:stylesheet>
    

    请注意以下内容中的单引号:

    <xsl:with-param name="replace" select="'icon1.gif'" />
    <xsl:with-param name="by" select="'icon2.gif'" /> 
    

    如果没有这些,模板将查找名为 icon1.gif icon2.gif 如果没有这样的节点,参数将为空,模板将进入无限循环。


    P.S.为了提高效率,请更改:

    <xsl:template match="Icon/href">
    

    至:

    <xsl:template match="Icon/href[contains(., 'icon1.gif')]">