xslt如何填补缺失的数字

时间:2014-08-20 01:06:02

标签: xslt

这是输入xml

    <?xml version="1.0" encoding="UTF-8"?>
        <record>
            <Tubes>
                <Tube carousel_pos="1" tube_pos="1">
                    <TubeID>FLW140000293A0101</TubeID>
                    <markers>
                        <marker position="4">MSIGG1-PC55</marker>
                        <marker position="9">MSIGG1-PB</marker>
                        <marker position="8">MSIGG1-APCAF750</marker>
                        <marker position="10">CD45-KO</marker>
                    </markers>
                </Tube>
                <Tube carousel_pos="2" tube_pos="2">
                    <TubeID>FLW140000293A0102</TubeID>
                    <markers>
                        <marker position="4">CD3-PC55</marker>
                        <marker position="9">CD8-PB</marker>
                        <marker position="8">CD4-APCAF750</marker>
                        <marker position="10">CD45-KO</marker>
                    </markers>
                </Tube>
            </Tubes>
        </record>

这是它应该输出的内容

        <p num="1">Empty</p>
        <p num="2">Empty</p>
        <p num="3">Empty</p>
        <p num="4">CD3-PC55</p>
        <p num="5">Empty</p>
        <p num="6">Empty</p>
        <p num="7">Empty</p>
        <p num="8">CD4-APCAF750</p>
        <p num="9">CD8-PB</p>
        <p num="10">CD45-KO</p>

这是我的xslt

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="#all"/>
    <xsl:template match="/record/Tubes/Tube">
        <xsl:for-each select="markers/marker">
            <xsl:sort select="@position" data-type="number"/>
            <xsl:choose>
                <xsl:when test="position() &lt; @position">
                    <xsl:call-template name="routine">
                        <xsl:with-param name="PC" select="position()"/>
                        <xsl:with-param name="PT" select="@position"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="routine">
    <xsl:param name="PC"/>
    <xsl:param name="PT"/>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

如果你能够使用XSLT 2.0,就像当前的XSLT一样,你应该能够使用递增循环,就像这样

 <xsl:for-each select="1 to 10">

首先创建一个包含所有marker元素的变量,获取最大@position属性

    <xsl:variable name="markers" select="markers/marker" />
    <xsl:variable name="max" select="max($markers/@position)" />

然后,你有xsl:for-each这样的循环:

<xsl:for-each select="1 to xs:integer($max)">

使用之前的markers变量来检查每个位置的元素是否存在是非常直接的

<xsl:variable name="position" select="position()" />
<xsl:choose>
    <xsl:when test="$markers[@position = $position]">

试试这个XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="#all">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/record/Tubes/Tube">
        <xsl:variable name="markers" select="markers/marker" />
        <xsl:variable name="max" select="max($markers/@position)" />
        <div>
            <xsl:for-each select="1 to xs:integer($max)">
                <xsl:variable name="position" select="position()" />
                <p num="{$position}">
                    <xsl:choose>
                        <xsl:when test="$markers[@position = $position]">
                            <xsl:value-of select="$markers[@position = $position]"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>Empty</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </p>
            </xsl:for-each>
        </div>
    </xsl:template>
</xsl:stylesheet>

这会产生以下输出(假设您希望每个tube元素单独执行此操作:

<div>
   <p num="1">Empty</p>
   <p num="2">Empty</p>
   <p num="3">Empty</p>
   <p num="4">MSIGG1-PC55</p>
   <p num="5">Empty</p>
   <p num="6">Empty</p>
   <p num="7">Empty</p>
   <p num="8">MSIGG1-APCAF750</p>
   <p num="9">MSIGG1-PB</p>
   <p num="10">CD45-KO</p>
</div>
<div>
   <p num="1">Empty</p>
   <p num="2">Empty</p>
   <p num="3">Empty</p>
   <p num="4">CD3-PC55</p>
   <p num="5">Empty</p>
   <p num="6">Empty</p>
   <p num="7">Empty</p>
   <p num="8">CD4-APCAF750</p>
   <p num="9">CD8-PB</p>
   <p num="10">CD45-KO</p>
</div>