Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 不修改变量的XSL方法_Xml_Xslt - Fatal编程技术网

Xml 不修改变量的XSL方法

Xml 不修改变量的XSL方法,xml,xslt,Xml,Xslt,我试图修改一个XSL样式表,该样式表将XML转换为CSV格式,在这种格式中,列的数量可能会有所不同,出现这种情况时需要一个新的标题行 我想存储一个带有当前标题的变量,并与前一个标题进行比较,如果两者不匹配,则输出当前标题 这种方法要求在下一次比较时更新前一个标题变量,XSL中不允许更新变量。因此,我正在寻找另一种方法 谢谢 一个简单的输出示例,三条记录产生五行输出,第2、3和5行是数据,第1和4行是标题行: First,Last John,Smith Sally,Ford First,Middl

我试图修改一个XSL样式表,该样式表将XML转换为CSV格式,在这种格式中,列的数量可能会有所不同,出现这种情况时需要一个新的标题行

我想存储一个带有当前标题的变量,并与前一个标题进行比较,如果两者不匹配,则输出当前标题

这种方法要求在下一次比较时更新前一个标题变量,XSL中不允许更新变量。因此,我正在寻找另一种方法

谢谢

一个简单的输出示例,三条记录产生五行输出,第2、3和5行是数据,第1和4行是标题行:

First,Last
John,Smith
Sally,Ford
First,Middle,Last
Frank,Anthony,Jones
输入

<People>
  <Person>
    <Index>1</Index>
    <Attribute>
      <Name>First</Name>
      <Value>John</Value>
    </Attribute>
    <Attribute>
      <Name>Last</Name>
      <Value>Smith</Value>
    </Attribute>
  </Person>
  <Person>
    <Index>2</Index>
    <Attribute>
      <Name>First</Name>
      <Value>Sally</Value>
    </Attribute>
    <Attribute>
      <Name>Last</Name>
      <Value>Ford</Value>
    </Attribute>
  </Person>
  <Person>
    <Index>3</Index>
    <Attribute>
      <Name>First</Name>
      <Value>Frank</Value>
    </Attribute>
    <Attribute>
      <Name>Middle</Name>
      <Value>Anthony</Value>
    </Attribute>
    <Attribute>
      <Name>Last</Name>
      <Value>Jones</Value>
    </Attribute>
  </Person>
</People>

1.
弗斯特
约翰
最后
史密斯
2.
弗斯特
俏皮话
最后
河流浅水处
3.
弗斯特
直率的
中间的
安东尼
最后
琼斯

这里有一种方法可以在XSLT1.0中使用

它首先只选择第一个
Person
元素。匹配(any)
Person
元素的模板有一个参数,其中包含前面的标题(最初)为空,然后从获取当前行的标题开始。 如果当前标头与上一个标头不同,则可以将其输出

然后它输出行本身,然后递归调用下一个
Person
元素,当前标题与前一个相同

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

    <xsl:template match="/People">
      <xsl:apply-templates select="Person[1]" />
    </xsl:template>

    <xsl:template match="Person">
        <xsl:param name="previous" />
        <xsl:variable name="current">
            <xsl:for-each select="Attribute">
                <xsl:if test="position() > 1">,</xsl:if>
                <xsl:value-of select="Name" />
            </xsl:for-each>
        </xsl:variable>
        <xsl:if test="$current != $previous">
            <xsl:value-of select="concat($current, '&#10;')" />
        </xsl:if>
        <xsl:for-each select="Attribute">
            <xsl:if test="position() > 1">,</xsl:if>
            <xsl:value-of select="Value" />
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="following-sibling::Person[1]">
            <xsl:with-param name="previous" select="$current" />
        </xsl:apply-templates>
    </xsl:template>
</xsl:stylesheet>

1:您可以发布您当前的XSLT尝试,或者至少发布相关的位;2:似乎最好只生成最大数量的列,并在不需要的地方使用空格/Null,是否有不这样做的原因?是否允许按属性集对记录进行排序(以便每个标题只显示一次)?如果是,您可以使用XSLT2.0吗?To Dan Field:我没有任何有意义的东西可以发布给XSLT。一个XSLT硬编码文件顶部的特定头,用于传统文件传输。另一个模板将头条目内联(例如First=John,Last=Smith),该文件需要一个辅助应用程序来处理为所需的格式,但对于当前的使用更灵活。Michael Hor:输出格式不可更改,在某些情况下排序可能会导致问题。样本数据被简化,可能的属性数量很大,因此不可能使用单个公共标题。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text" />

    <xsl:template match="/People">
        <xsl:for-each-group select="Person" group-adjacent="string-join(Attribute/Name, ',')">
            <xsl:value-of select="current-grouping-key()" />
            <xsl:text>&#10;</xsl:text>
            <xsl:for-each select="current-group()">
                <xsl:value-of select="Attribute/Value" separator="," />
                <xsl:text>&#10;</xsl:text>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>