Xml XSL可以';我找不到数据转换的解决方案

Xml XSL可以';我找不到数据转换的解决方案,xml,xslt,Xml,Xslt,我有这样的XML: <ROW ref="0005631" type="04" line="1" value="Australia"/> <ROW ref="0005631" type="00" line="1" value="John"/> <ROW ref="0005631" type="02" line="1" value="Builder"/> <ROW ref="0005631" type="01" line="1" value="Smith"/

我有这样的XML:

<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>

任何帮助都会很好。我有很多不同的数据,很多不同的类型和行都是混合的,所以我不想硬编码任何数据。

你的意思是,你想从同一行中获取元素,然后根据类型编号显示它吗?我认为,要对数据使用
xsl:sort
,您需要有一个父节点,该节点在示例代码中没有提供,但必须有一个才能使XML文档有效。假设父节点是
,您的输入将是

<TABLE>
    <ROW ref="0005631" type="04" line="1" value="Australia"/>
    <ROW ref="0005631" type="00" line="1" value="John"/>
    <ROW ref="0005631" type="02" line="1" value="Builder"/>
    <ROW ref="0005631" type="01" line="1" value="Smith"/>
</TABLE>
我无法从您的问题中准确确定您想要的排序顺序,但考虑到这两个示例,任何备选方案都应该是直截了当的。

在XSLT 1.0中:

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

  <!-- index ROWs by their @ref -->
  <xsl:key name="kRowByRef"        match="ROW" use="@ref" />
  <!-- index ROWs by their @ref and @line -->
  <xsl:key name="kRowByRefAndLine" match="ROW" use="concat(@ref, ',', @line)" />

  <xsl:template match="/*">
    <!-- 1) rows are processed with "ORDER BY @ref" -->
    <xsl:apply-templates select="ROW" mode="ref-group">
      <xsl:sort select="@ref"  data-type="number" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="ROW" mode="ref-group">
    <!-- 2) rows are grouped by @ref -->
    <xsl:variable name="thisGroup" select="
      key('kRowByRef', @ref)
    " />

    <xsl:if test="generate-id() = generate-id($thisGroup[1])">
      <!-- 2.1) for the first item in the group, 
                nodes are processed with "ORDER BY @line" -->
      <xsl:apply-templates select="$thisGroup" mode="line-group">
        <xsl:sort select="@line" data-type="number" />
      </xsl:apply-templates>
      <!-- use a line as record separator -->
      <xsl:text>----------------------------&#10;</xsl:text>
    </xsl:if>
  </xsl:template>

  <xsl:template match="ROW" mode="line-group">
    <!-- 3) rows are grouped by @ref, @line -->
    <xsl:variable name="thisGroup" select="
      key('kRowByRefAndLine', concat(@ref, ',', @line))
    " />

    <xsl:if test="generate-id() = generate-id($thisGroup[1])">
      <!-- 3.1) for the first item in the group, 
                nodes are processed with "ORDER BY @type" -->
      <xsl:apply-templates select="$thisGroup" mode="line">
        <xsl:sort select="@type" data-type="number" />
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>

  <xsl:template match="ROW" mode="line">
    <!-- 4) rows are printed out & appended with space or newline -->
    <xsl:value-of select="@value" />
    <xsl:choose>
      <xsl:when test="position() = last()">
        <xsl:text>&#10;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
模板2仅处理每个
@ref
组的第一个:

<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
模板#3取每个
@行的第一行
组:

<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>

模板#4将它们打印出来,并在适当的地方添加空格或换行符。

那么您要求的是XSLT文档?你能告诉我们到目前为止你都做了些什么吗?我认为这并不像排序那么简单。我有数百个参考资料,参考资料有很多行。所以我需要能够以某种方式将行号链接到引用,并输出所有属于该行的项目。所有的数据都是随机排列的,所以我无法遍历数据。@Ben,那么也许你应该:a.给出一个更大的XML示例;B.更清楚地解释你的要求是什么;C.给出一个更大的预期产出示例;和D.显示到目前为止xsl的外观。非常好,谢谢。我能够修改您的代码,以完全满足我的需要。
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output method="text" encoding="utf-8" />

  <!-- index ROWs by their @ref -->
  <xsl:key name="kRowByRef"        match="ROW" use="@ref" />
  <!-- index ROWs by their @ref and @line -->
  <xsl:key name="kRowByRefAndLine" match="ROW" use="concat(@ref, ',', @line)" />

  <xsl:template match="/*">
    <!-- 1) rows are processed with "ORDER BY @ref" -->
    <xsl:apply-templates select="ROW" mode="ref-group">
      <xsl:sort select="@ref"  data-type="number" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="ROW" mode="ref-group">
    <!-- 2) rows are grouped by @ref -->
    <xsl:variable name="thisGroup" select="
      key('kRowByRef', @ref)
    " />

    <xsl:if test="generate-id() = generate-id($thisGroup[1])">
      <!-- 2.1) for the first item in the group, 
                nodes are processed with "ORDER BY @line" -->
      <xsl:apply-templates select="$thisGroup" mode="line-group">
        <xsl:sort select="@line" data-type="number" />
      </xsl:apply-templates>
      <!-- use a line as record separator -->
      <xsl:text>----------------------------&#10;</xsl:text>
    </xsl:if>
  </xsl:template>

  <xsl:template match="ROW" mode="line-group">
    <!-- 3) rows are grouped by @ref, @line -->
    <xsl:variable name="thisGroup" select="
      key('kRowByRefAndLine', concat(@ref, ',', @line))
    " />

    <xsl:if test="generate-id() = generate-id($thisGroup[1])">
      <!-- 3.1) for the first item in the group, 
                nodes are processed with "ORDER BY @type" -->
      <xsl:apply-templates select="$thisGroup" mode="line">
        <xsl:sort select="@type" data-type="number" />
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>

  <xsl:template match="ROW" mode="line">
    <!-- 4) rows are printed out & appended with space or newline -->
    <xsl:value-of select="@value" />
    <xsl:choose>
      <xsl:when test="position() = last()">
        <xsl:text>&#10;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text> </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
<data>
  <ROW ref="0005631" type="04" line="1" value="Australia"/>
  <ROW ref="0005632" type="00" line="1" value="Jack"/>
  <ROW ref="0005631" type="00" line="1" value="John"/>
  <ROW ref="0005631" type="01" line="1" value="Smith"/>
  <ROW ref="0005632" type="04" line="2" value="Whiskey"/>
  <ROW ref="0005632" type="02" line="1" value="Tennessee"/>
  <ROW ref="0005631" type="02" line="1" value="Builder"/>
  <ROW ref="0005632" type="01" line="1" value="Daniel's"/>
</data>
John Smith Builder Australia ---------------------------- Jack Daniel's Tennessee Whiskey ----------------------------
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>

<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
<ROW ref="0005631" type="04" line="1" value="Australia"/>
<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="04" line="2" value="Whiskey"/>
<ROW ref="0005631" type="00" line="1" value="John"/>
<ROW ref="0005631" type="01" line="1" value="Smith"/>
<ROW ref="0005631" type="02" line="1" value="Builder"/>
<ROW ref="0005631" type="04" line="1" value="Australia"/>

<ROW ref="0005632" type="00" line="1" value="Jack"/>
<ROW ref="0005632" type="01" line="1" value="Daniel's"/>
<ROW ref="0005632" type="02" line="1" value="Tennessee"/>

<ROW ref="0005632" type="04" line="2" value="Whiskey"/>