2012-06-02 62 views
3

我真的是这个XSLT世界的新手。我面临的问题是将单个XML节点中存在的值分开。使用XSLT 1.0分割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来实现这一点?

您的帮助将不胜感激。

+0

这个XML从哪里来?修复上游逻辑以创建多个'MobileNo'字段,因此您不必自己解析它。 XML在哪里?你也可以修改下游逻辑来解析它,它可以像'split(' - ')'一样简单。换句话说,你为什么决定使用XSL转换来做到这一点?此外,使用XSLT 1.0的自我限制的性质是什么? – 2012-06-02 17:25:54

回答

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

这里是一个完整的,更短,更简单(无xsl:choose,没有xsl:when,没有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. 使用定点以避免不必要的条件指示。