XSL中的复杂自动编号

时间:2014-09-08 12:38:49

标签: xml xslt

我想知道如何在XSL中创建不同的自动编号系列。我理解我需要转换文件的结构相当复杂,而且不必要地拜占庭。但是,我认为这真的是我需要的......我用简单的位置()得到了它的工作,但我在网上找不到可能带我前进的类似案例的信息。所以这就是:

XML就像这样:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test.xsl" type="text/xsl"?>
<XML>
<thing>line</thing>
<thing>line</thing>
<thing>line</thing>
<thing>line</thing>
</XML>

我需要一个像这样的结构:

<XML>
<ids>
<id id="1" nr="0"/>
<id id="2" nr="10"/>
<id id="3" nr="20"/>
<id id="4" nr="30"/>
<id id="5" nr="40"/>
<id id="6" nr="50"/>
<id id="7" nr="60"/>
<id id="8" nr="70"/>
</ids>
<info_things>
<thing thing_id="1" id1="1" id2="2"></thing>
<thing thing_id="2" id1="3" id2="4"></thing>
<thing thing_id="3" id1="5" id2="6"></thing>
<thing thing_id="4" id1="7" id2="8"></thing>
</info_things>
<things>
<thing thing_id="5" ref_id="1">line</thing>
<thing thing_id="6" ref_id="2">line</thing>
<thing thing_id="7" ref_id="3">line</thing>
<thing thing_id="8" ref_id="4">line</thing>
</things>
</XML>

这分为几个仍未解决的子问题:

  1. 所以我需要生成两倍于我原始节点的id。
  2. 对于id nr,我想生成一个从0开始并增加10的列表,但它也可以从现在开始的10开始,这是可以接受的。
  3. 你的身份必须是独一无二的,所以他们必须从他们留下的地方继续......
  4. 我现在有这个:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output method="xml" omit-xml-declaration="no" />
    <xsl:template match="/">
     <XML>
        <ids>
           <xsl:for-each select="//thing">
               <id id="{position()}" nr="{position()*10}"/>
           </xsl:for-each>
        </ids>
        <info_things>
            <xsl:for-each select="//thing">
                <thing thing_id="{position()}" id1="{position()*2-1}" id2="{position()*2}"></thing>
            </xsl:for-each>
        </info_things>
        <things>
            <xsl:for-each select="//thing">
                <thing thing_id="{position()}" ref_id="{position()}">line</thing>
            </xsl:for-each>
        </things>
    </XML>
    </xsl:template>
    </xsl:stylesheet>
    

    它输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <XML>
    <ids>
        <id id="1" nr="10"/>
        <id id="2" nr="20"/>
        <id id="3" nr="30"/>
        <id id="4" nr="40"/>
    </ids>
    <info_things>
        <thing thing_id="1" id1="1" id2="2"/>
        <thing thing_id="2" id1="3" id2="4"/>
        <thing thing_id="3" id1="5" id2="6"/>
        <thing thing_id="4" id1="7" id2="8"/>
    </info_things>
    <things>
        <thing thing_id="1" ref_id="1">line</thing>
        <thing thing_id="2" ref_id="2">line</thing>
        <thing thing_id="3" ref_id="3">line</thing>
        <thing thing_id="4" ref_id="4">line</thing>
    </things>
    </XML>
    

    这仍然存在id不被复制的数量以及thing_id不唯一的问题。据我所知,当id正在工作时,id nr也不可能由简单的位置生成。我尝试声明变量,但这并没有真正帮助。

    谢谢!

    更新:

    我意识到我忘记了一个我试图实现的模式。理想情况下,我会有id nr的模式:

    <id id="1" nr="0"/>
    <id id="2" nr="10"/>
    <id id="3" nr="10"/>
    <id id="4" nr="20"/>
    <id id="5" nr="20"/>
    <id id="6" nr="30"/>
    <id id="7" nr="30"/>
    <id id="8" nr="40"/>
    

    对不起! Lingamurthy CS的答案做了我要求的一切,非常感谢!

1 个答案:

答案 0 :(得分:1)

稍作修改。 1.使用xs:integer将cast计数类型转换为整数并迭代//计算事物数量以生成&#34; id&#34; s,并使用position() - 1从0开始获取nr。 2.使用count(// thing)添加position()以继续thing_id。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" omit-xml-declaration="no" />
<xsl:template match="/">
    <XML>
        <ids>
            <xsl:for-each select="1 to xs:integer(count(//thing) * 2)">
                <id id="{position()}" nr="{(position() - 1)*10}"/>
            </xsl:for-each>
        </ids>
        <info_things>
            <xsl:for-each select="//thing">
                <thing thing_id="{position()}" id1="{position()*2-1}" id2="{position()*2}"/>
            </xsl:for-each>
        </info_things>
        <things>
            <xsl:for-each select="//thing">
                <thing thing_id="{position() + count(//thing)}" ref_id="{position()}">line</thing>
            </xsl:for-each>
        </things>
    </XML>
</xsl:template>
</xsl:stylesheet>