3

我真的是这个 XSLT 世界的新手。我面临拆分单个 XML 节点中存在的值的问题。

例如,我的输入 XML 包含以下数据:

<Employee>
  <FirstName>AAA</FirstName>
  <LastName>BBB</LastName>
  <MobileNo>9999999999-6666666666-7777777777</MobileNo>
</Employee>

在上面的示例中,员工可以有多个手机号码,因此他的所有手机号码都合并到一个 XML 节点<MobileNo>中。用连字符(-)隔开手机号码,意思9999999999是第一个手机号,6666666666第二个手机号,7777777777第三个手机号。员工可以拥有任意数量的手机号码。

Myy 输出 XML 应具有以下结构。

<Employee>
  <FirstName>AAA</FirstName>
  <LastName>BBB</LastName>
  <MobileNo>9999999999</MobileNo>
  <MobileNo>6666666666</MobileNo>
  <MobileNo>7777777777</MobileNo>
</Employee>

那么如何使用 XSLT 1.0 实现这一点呢?

您的帮助将不胜感激。

4

2 回答 2

4

这是一个完整、更短且更简单(no xsl:choose, no xsl:when, no xsl:otherwise)的 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:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="MobileNo" name="split">
  <xsl:param name="pText" select="."/>

  <xsl:if test="$pText">
   <MobileNo>
     <xsl:value-of select="substring-before(concat($pText, '-'), '-')"/>
   </MobileNo>

   <xsl:call-template name="split">
     <xsl:with-param name="pText" select="substring-after($pText, '-')"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<Employee>
    <FirstName>AAA</FirstName>
    <LastName>BBB</LastName>
    <MobileNo>9999999999-6666666666-7777777777</MobileNo>
</Employee>

产生了想要的正确结果:

<Employee>
   <FirstName>AAA</FirstName>
   <LastName>BBB</LastName>
   <MobileNo>9999999999</MobileNo>
   <MobileNo>6666666666</MobileNo>
   <MobileNo>7777777777</MobileNo>
</Employee>

说明

  1. 递归调用命名模板 ( split)。

  2. 停止条件是传递的参数是空的节点集/字符串。

  3. 使用哨兵来避免不必要的条件指令。

于 2012-06-02T15:25:24.967 回答
0

您必须将其编写为递归命名模板。下面的代码显示了这个想法。

此处的命名模板split-mobile传递了一个带有可能连字符的字符串,其中必须拆分字符串。

调用substring-before获取第一个号码。如果字符串不包含连字符,这将返回一个空字符串(计算结果为false )。

一个<xsl:choose>元素输出元素内的第一个数字,如果它是连字符的,则使用字符串的其余部分进行<MobileNo>调用。substring-before否则输出整个字符串。

<xsl:template match="MobileNo">
  <xsl:call-template name="split-mobile" >
    <xsl:with-param name="numbers" select="text()" />
  </xsl:call-template>
</xsl:template>


<xsl:template name="split-mobile">

  <xsl:param name="numbers" />
  <xsl:variable name="number" select="substring-before($numbers, '-')" />

  <xsl:choose>

    <xsl:when test="$number">
      <MobileNo>
        <xsl:value-of select="$number" />
      </MobileNo>
      <xsl:call-template name="split-mobile">
        <xsl:with-param name="numbers" select="substring-after($numbers, '-')"/>
      </xsl:call-template>
    </xsl:when>

    <xsl:otherwise>
      <MobileNo>
        <xsl:value-of select="$numbers" />
      </MobileNo>
    </xsl:otherwise>

  </xsl:choose>

</xsl:template>
于 2012-06-02T13:00:02.150 回答