XSLT:拆分字符串并对每个字符执行某些操作

时间:2011-04-11 23:15:58

标签: xml xslt

我是XSLT的新手。我已经阅读了这些教程,并且通过我的XML文档,我已经能够完成大约80%的工作。但是,我被困在某事上。在我的XML文档中,我有一些属性,包括“ERA”,“EDA”,“EDAR”等值。基本上这些属性由字母E,D,A和R的组合组成.E,D,A和R映射到编辑删除添加阅读

如果我正在执行此命令,我会将字符串拆分为其组成字符,然后检查每个字符以查看是否应输出编辑删除添加阅读。我怎样才能在XSLT中做类似的事情?我正在考虑使用长度和子串函数并进行某种循环。

3 个答案:

答案 0 :(得分:1)

假设该属性仅包含E D A和R(或者您不关心其他可能的值),contains(@attr,...)中的一组简单<xsl:choose...>应该可以正常工作:

<xsl:choose>
  <xsl:when test="contains(@attr,'A')">
    ...
  </xsl:when>
  <xsl:when test="contains(@attr,'D')">
    ...
  </xsl:when>
  etc...
</xsl:choose>

答案 1 :(得分:1)

内联(或外部)地图:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:local="http://localhost">
    <local:map letter="E" text="Edit"/>
    <local:map letter="D" text="Delete"/>
    <local:map letter="A" text="Add"/>
    <local:map letter="R" text="Read"/>
    <xsl:template match="test">
        <xsl:copy>
            <xsl:apply-templates
             select="document('')/*/local:map[
                        contains(current(),@letter)
                     ]/@text"
             mode="sequence"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="node()|@*" mode="sequence">
        <xsl:value-of select="concat(substring(' ', 1 div (position()!=1)),.)"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<test>Edit Delete Add Read</test>

xsl:if说明的顺序:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="test">
        <xsl:copy>
            <xsl:if test="contains(.,'E')">Edit </xsl:if>
            <xsl:if test="contains(.,'D')">Delete </xsl:if>
            <xsl:if test="contains(.,'A')">Add </xsl:if>
            <xsl:if test="contains(.,'R')">Read </xsl:if>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<test>Edit Delete Add Read </test>

答案 2 :(得分:0)

我能够通过使用递归函数/模板来解决这个问题:

<xsl:template name="translateAccessModes">

 <xsl:param name="accessModes" />

 <xsl:if test="string-length($accessModes) > 0">

  <xsl:variable name="accessMode" select="substring($accessModes, 1, 1)" />
  <xsl:choose>
   <xsl:when test="$accessMode='E'">Edit </xsl:when>
   <xsl:when test="$accessMode='D'">Delete </xsl:when>
   <xsl:when test="$accessMode='A'">Add </xsl:when>
   <xsl:when test="$accessMode='R'">Read </xsl:when>
   <xsl:otherwise>Unrecognized Access Mode: <xsl:value-of select="$accessMode" /> </xsl:otherwise>
  </xsl:choose>

  <xsl:call-template name="translateAccessModes">
   <xsl:with-param name="accessModes" select="substring($accessModes, 2, string-length($accessModes))" />
  </xsl:call-template>

 </xsl:if>

</xsl:template>

不确定这是否是最佳方式。