XSL:替换标记内的值

时间:2016-04-14 11:10:32

标签: xslt xslt-1.0

输入:

<Remarks>Random data## B2B## abc,controls,free text ## B2B## random data</Remarks>

XSL应该替换

  

&#34; ## B2B ## abc,控件,自由文本## B2B ##&#34;

带有

的备注标记中的

  

&#34; value1:abc,value2:controls,value3:free text&#34;

期望的输出:

<Remarks>Random data,value1:abc,value2:controls,value3:free text,random data</Remarks>

注意:## B2B##标记内的值是未知的,每次都会更改,现在我给出了示例值。

2 个答案:

答案 0 :(得分:0)

这个解决方案有点复杂。它使用一个模板提取标记之间的字符串,另一个模板用分隔符分隔此字符串。什么字符串被其他字符串外包到包含映射(replacement.xml)的另一个文件。因为XSLT-1.0在变量中返回RTF(结果树片段),所以替换在模板中是硬编码的。在XSLT-2.0中,您可以使用变量来使解决方案更加灵活。

以下是包含映射的replacement.xml

<?xml version="1.0" encoding="UTF-8"?>
<replacement>
  <r src="abc">value1</r>
  <r src="controls">value2</r>
  <r src="free text">value3</r>
</replacement>

XSLT将这些映射合并到字符串中:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/lines/Remarks">
      <xsl:variable name="tagName" select="'## B2B##'" />
      <xsl:variable name="subStrToReplace">
        <xsl:call-template name="strInTag">
          <xsl:with-param name="str" select="text()" />
          <xsl:with-param name="tagName" select="$tagName" />
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="replacementString">
        <xsl:call-template name="splitAndReplace">
          <xsl:with-param name="pText" select="$subStrToReplace" />
        </xsl:call-template>
      </xsl:variable>
      <Remarks>
        <xsl:value-of select="concat(normalize-space(substring-before(text(),$tagName)), ',',$replacementString, normalize-space(substring-after(substring-after(text(),$tagName),$tagName)))" />
      </Remarks>
    </xsl:template>

    <xsl:template name="strInTag">
      <xsl:param name="str" />
      <xsl:param name="tagName" />
      <xsl:value-of select="normalize-space(substring-before(substring-after($str,$tagName),$tagName))" />
    </xsl:template>

    <xsl:template name="splitAndReplace">
      <xsl:param name="pText"/>
      <xsl:if test="string-length($pText) > 0">
        <xsl:variable name="vNextItem" select="substring-before(concat($pText, ','), ',')"/>
        <xsl:value-of select="concat($vNextItem,':',document('replacement.xml')/replacement/r[@src = $vNextItem]/text(),',')"/>
        <xsl:call-template name="splitAndReplace">
          <xsl:with-param name="pText" select="substring-after($pText, ',')"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

假设始终只有一个“占位符”由## B2B##分隔,并且它将始终包含完全 3个以逗号分隔的“令牌”,您可以通过简单的方式完成此操作:

<xsl:template match="Remarks">
    <xsl:copy>
        <xsl:value-of select="substring-before(., '## B2B##')" />

        <xsl:variable name="placeholder" select="substring-before(substring-after(., '## B2B##'), '## B2B##')" />
        <xsl:text> value1: </xsl:text>
        <xsl:value-of select="substring-before($placeholder, ',')" />
        <xsl:text> value2: </xsl:text>
        <xsl:value-of select="substring-before(substring-after($placeholder, ','), ',')" />
        <xsl:text> value3: </xsl:text>
        <xsl:value-of select="substring-after(substring-after($placeholder, ','), ',')" />

        <xsl:value-of select="substring-after(substring-after(., '## B2B##'), '## B2B##')" />
    </xsl:copy>
</xsl:template>