【问题标题】:Converting rows into nested elements with xslt使用 xslt 将行转换为嵌套元素
【发布时间】:2014-01-01 21:15:18
【问题描述】:

输入:

<data>
  <line>1grandparent-fname</line>
  <line>2parentfname</line>
  <line>3child1name</line>
  <line>4child2name</line>
  <line>3child1name</line>
  <line>4child2name</line>
  <line>5parent-lname</line>
  <line>6grandparent-lname</line>
</data>

预期输出:

<data>
  <grandparent fname="Grandparent-fname" lname="grandparent-lname">
    <parent fname="parentfname" lname="parent-lname">
      <child1>child1name</child1>
      <child2>child2name</child2>
      <child1>child1name</child1>
      <child2>child2name</child2>
    </parent>
  </grandparent>
</data>

关于如何使用 xslt 完成的任何想法?尝试了各种选项,但无法弄清楚。

第一个字母决定层次结构,1 个祖父 fname,2 个父 fname,3 个子 fname,以此类推。父母和孩子重复,孩子1和2将是连续的,

【问题讨论】:

  • 只有一个祖父母吗?
  • 是的。一位祖父母。

标签: xslt


【解决方案1】:

这是一种可能的方法。它可能不是一个优雅的,但输入也不是。假设可以有不止一个祖父母和任意数量(包括奇数)的孩子。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/data">
<xsl:copy>
    <xsl:apply-templates select="line[starts-with(., '1')]">
        <xsl:with-param name="level" select="'grandparent'"/>
    </xsl:apply-templates>
</xsl:copy>
</xsl:template>

<xsl:template match="line">
    <xsl:param name="level"/>
    <xsl:choose>
        <xsl:when test="$level='grandparent'">
            <xsl:variable name="end" select="following-sibling::line[starts-with(., '6')][1]" />
            <xsl:variable name="limit" select="count($end/preceding-sibling::line)" />
            <grandparent>
                <xsl:attribute name="fname">
                    <xsl:value-of select="substring(., 2)"/>
                </xsl:attribute>
                <xsl:attribute name="lname">
                    <xsl:value-of select="substring($end, 2)"/>
                </xsl:attribute>
                <xsl:apply-templates select="following-sibling::line[count(preceding-sibling::line) &lt; $limit][starts-with(., '2')]">
                    <xsl:with-param name="level" select="'parent'"/>
                </xsl:apply-templates>
            </grandparent>
        </xsl:when>

        <xsl:when test="$level='parent'">
            <xsl:variable name="end" select="following-sibling::line[starts-with(., '5')][1]" />
            <xsl:variable name="limit" select="count($end/preceding-sibling::line)" />
            <parent>
                <xsl:attribute name="fname">
                    <xsl:value-of select="substring(., 2)"/>
                </xsl:attribute>
                <xsl:attribute name="lname">
                    <xsl:value-of select="substring($end, 2)"/>
                </xsl:attribute>
                <xsl:apply-templates select="following-sibling::line[count(preceding-sibling::line) &lt; $limit][starts-with(., '3') or starts-with(., '4')]">
                    <xsl:with-param name="level" select="'child'"/>
                </xsl:apply-templates>
            </parent>
        </xsl:when>

        <xsl:when test="$level='child'">
            <child>
                <xsl:value-of select="substring(., 2)"/>    
            </child>
        </xsl:when>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet> 

【讨论】:

  • 谢谢。它的工作。如果行标签在文件标签 TXTTXT
  • @user2288031 请不要在 cmets 中发布代码;相反,请为您的原始问题添加后续内容。在任何情况下,所需的修改都是微不足道的,您应该能够自己解决 - 假设"a minimal understanding of the problem being solved"
猜你喜欢
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
相关资源
最近更新 更多