【问题标题】:Generating sequence number in XSLT for parent child elements在 XSLT 中为父子元素生成序列号
【发布时间】:2015-06-22 07:39:55
【问题描述】:

我正在尝试为我的输入 xml 生成两种类型的序列号,其中重复包含父元素和子元素。输入见下文

我有一个像这样的输入 xml:

<family>
 <parent>P1<parent>
 <child>C1<child>
</family>
<family>
 <parent>P1<parent>
 <child>C2<child>
</family>
<family>
 <parent>P2<parent>
 <child>C3<child>
</family>
<family>
 <parent>P2<parent>
 <child>C4<child>
</family>
<family>
 <parent>P2<parent>
 <child>C5<child>
</family>

我的预期输出是包含内容的文本文件:

00001 C1 00001
00001 C2 00002
00002 C3 00001
00002 C4 00002
00002 C5 00003

第一个序列号基于父级,第二个基于子级。 我尝试在我的 xsl 中使用

<xsl:for-each-group select="family" group-by="child">
  <xsl:value-of select="format-number(position(),'00000')"/>
  <xsl:value-of select="child"/>
  <xsl:value-of select="format-number(position(),'00000')"/>
</xsl:for-each-group>

对于上面的 xsl,我得到了双方相同的序列号。是否有任何特定的功能或分组概念可以实现,以便我可以实现所需的输出? 请帮我梳理一下这个逻辑。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    假设您的实际 XML 格式正确,您需要在此处使用两个 xsl:for-each-group 元素。一个按parent 分组,然后嵌套一个按child 分组当前组

    <xsl:for-each-group select="family" group-by="parent">
        <xsl:variable name="parentPos" select="format-number(position(),'00000')" />
        <xsl:for-each-group select="current-group()" group-by="child">
            <xsl:value-of select="$parentPos"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="child"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="format-number(position(),'00000')"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each-group>
    </xsl:for-each-group>
    

    【讨论】:

    • 蒂姆,我对此有一个小疑问,我如何提取所有父节点的最后一个子节点?例如:C2,C5
    • 您可以在外部 for-each-group 循环中执行类似 current-group()[last()] 的操作。如果你不能让它工作,请随时在 SO 上提出一个全新的问题。谢谢!
    • 我明白了,我使用了 if 条件 position()=last() 来获取第二个循环中的最后一个元素。
    【解决方案2】:

    我不明白为什么你需要按孩子分组。不是每个孩子都是独一无二的吗?如果是这样,这样做就足够了:

    <xsl:for-each-group select="family" group-by="parent">
        <xsl:variable name="group-number" select="position()" />
        <xsl:for-each select="current-group()/child">
            <xsl:value-of select="format-number($group-number,'00000')"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="format-number(position(),'00000')"/>
            <xsl:text>&#10;</xsl:text>          
        </xsl:for-each>
    </xsl:for-each-group> 
    

    注意:您的输入似乎已按parent 排序;在这种情况下,您可以使用:

    <xsl:for-each-group select="family" group-adjacent="parent">
    

    【讨论】:

    • 是的,你是对的,按独生子女分组是一个错误。但感谢“组相邻”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-13
    • 2016-03-02
    • 2011-05-02
    • 2023-04-02
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多