Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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
是否可以使用XSLT2.0将节省的XML转换为完整的HTML表?_Xml_Xslt_Xslt 2.0_Qxmlquery - Fatal编程技术网

是否可以使用XSLT2.0将节省的XML转换为完整的HTML表?

是否可以使用XSLT2.0将节省的XML转换为完整的HTML表?,xml,xslt,xslt-2.0,qxmlquery,Xml,Xslt,Xslt 2.0,Qxmlquery,非常重要的一点:我使用的是QtXmlPattern(一个未完全实现的XSLT2.0处理器,在实现过程中有一些bug…) 我有一个格式良好的XML文件,其中的数据定义在四级数组中,如下所示: <a> <b> <c day="20150221"> <d>...</d> <e>...</e> </c> <c day="20150222">

非常重要的一点:我使用的是QtXmlPattern(一个未完全实现的XSLT2.0处理器,在实现过程中有一些bug…)

我有一个格式良好的XML文件,其中的数据定义在四级数组中,如下所示:

<a>
  <b>
    <c day="20150221">
      <d>...</d>
      <e>...</e>
    </c>
    <c day="20150222">
      <d>...</d>
      <e>...</e>
    </c>
    <c day="20150223">
      <d>...</d>
      <e>...</e>
    </c>
  </b>
  <b>
    <c day="20150219">
      <d>...</d>
      <e>...</e>
    </c>
    <c day="20150221">
      <d>...</d>
      <e>...</e>
    </c>
    <c day="20150223">
      <d>...</d>
      <e>...</e>
    </c>
  </b>
  ...
</a>

...
...
...
...
...
...
...
...
...
...
...
...
...
结果应该包括所有的天数,但正如我们所看到的,每个
列表可能有不同的天数。然而,结果需要包含所有
标记的所有日期。如果数据不可用,结果将保持为空或可能为零

我找到了一种方法,可以将所有的日期收集到一个变量中:

<xsl:variable name="days" select="distinct-values(/a/b/c/@day)"/>

但我不知道如何生成最终结果,它看起来像这样:

<table>
  <th>
    <td>20150219</td>
    <td>20150221</td>
    <td>20150222</td>
    <td>20150223</td>
  </th>
  <tr>
    <td>data from <d> tag on 20150219</td>
    <td>data from <d> tag on 20150221</td>
    <td>data from <d> tag on 20150222</td>
    <td>data from <d> tag on 20150223</td>
  </tr>
  ...[repeat for various data and calculation on the data]...
</table>

20150219
20150221
20150222
20150223
来自20150219标签的数据
来自20150221上标签的数据
数据来自20150222上的标签
来自20150223上标签的数据
…[对各种数据和数据计算重复]。。。
我的问题是变量不是节点列表,只是字符串列表,我不太确定如何循环遍历字符串列表

以防万一,对于那些不了解QXmlQuery解析器的人来说,
xsl:for each group
命令并不存在。

您可以(使用XSLT 2.0,不确定您选择的处理器是否支持该命令)简单地执行

<xsl:variable name="main-doc" select="/">
带有三个参数的
key()
调用在XSLT2.0中是新的,如果不支持,请尝试

<xsl:for-each select="$days">
  <xsl:variable name="day" select="."/>
  <xsl:for-each select="$main-doc">
    <xsl:variable name="d-on-day" select="key('by-date', $day)"/>
    ...
  </xsl:for-each>
  ...
</xsl:for-each>
您可以(使用XSLT2.0,不确定您选择的处理器是否支持它)简单地执行以下操作

<xsl:variable name="main-doc" select="/">
带有三个参数的
key()
调用在XSLT2.0中是新的,如果不支持,请尝试

<xsl:for-each select="$days">
  <xsl:variable name="day" select="."/>
  <xsl:for-each select="$main-doc">
    <xsl:variable name="d-on-day" select="key('by-date', $day)"/>
    ...
  </xsl:for-each>
  ...
</xsl:for-each>

我不太确定你需要什么,但有时对尝试的解决方案发表评论比解释更容易。您肯定必须使用键来查找不同的属性值

不要在字符串列表中循环,而是通过一系列
c
元素循环,这些元素的
day
属性的值是唯一的(最终是相同的)。我在下面使用的技术由Jeni Tennison描述,因为它通常用于分组问题

XML输入

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:key name="day-from-c" match="c" use="@day" />

    <xsl:template match="/">
      <hmtl>
        <xsl:apply-templates/>
      </hmtl>
    </xsl:template>

    <xsl:template match="a">
        <table>

            <xsl:variable name="days" select="b/c[generate-id() =
        generate-id(key('day-from-c', @day)[1])]"/>

            <xsl:for-each select="$days">
                <xsl:sort select="@day"/>
                <th>
                    <xsl:value-of select="@day"/>
                </th>
            </xsl:for-each>
            <tr>
                <xsl:for-each select="$days">
                    <xsl:sort select="@day"/>
                    <td>
                        <xsl:value-of select="/a/b/c[@day = current()/@day]/d"/>
                    </td>
                </xsl:for-each>
            </tr>
        </table>
    </xsl:template>

</xsl:transform>
在我看来,合理的输入包括
d
元素的实际值:

<?xml version="1.0" encoding="UTF-8"?>
<a>
  <b>
    <c day="20150221">
      <d>data from day 20150221</d>
      <e>...</e>
    </c>
    <c day="20150222">
      <d>data from day 20150222</d>
      <e>...</e>
    </c>
    <c day="20150223">
      <d>data from day 20150223</d>
      <e>...</e>
    </c>
  </b>
  <b>
    <c day="20150219">
      <d>data from day 20150219</d>
      <e>...</e>
    </c>
    <c day="20150221">
      <d>data from day 20150221</d>
      <e>...</e>
    </c>
    <c day="20150223">
      <d>data from day 20150223</d>
      <e>...</e>
    </c>
  </b>
  <!--...-->
</a>

试试这个解决方案。

我不太确定您需要什么,但有时对尝试的解决方案发表评论比解释更容易。您肯定必须使用键来查找不同的属性值

不要在字符串列表中循环,而是通过一系列
c
元素循环,这些元素的
day
属性的值是唯一的(最终是相同的)。我在下面使用的技术由Jeni Tennison描述,因为它通常用于分组问题

XML输入

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:key name="day-from-c" match="c" use="@day" />

    <xsl:template match="/">
      <hmtl>
        <xsl:apply-templates/>
      </hmtl>
    </xsl:template>

    <xsl:template match="a">
        <table>

            <xsl:variable name="days" select="b/c[generate-id() =
        generate-id(key('day-from-c', @day)[1])]"/>

            <xsl:for-each select="$days">
                <xsl:sort select="@day"/>
                <th>
                    <xsl:value-of select="@day"/>
                </th>
            </xsl:for-each>
            <tr>
                <xsl:for-each select="$days">
                    <xsl:sort select="@day"/>
                    <td>
                        <xsl:value-of select="/a/b/c[@day = current()/@day]/d"/>
                    </td>
                </xsl:for-each>
            </tr>
        </table>
    </xsl:template>

</xsl:transform>
在我看来,合理的输入包括
d
元素的实际值:

<?xml version="1.0" encoding="UTF-8"?>
<a>
  <b>
    <c day="20150221">
      <d>data from day 20150221</d>
      <e>...</e>
    </c>
    <c day="20150222">
      <d>data from day 20150222</d>
      <e>...</e>
    </c>
    <c day="20150223">
      <d>data from day 20150223</d>
      <e>...</e>
    </c>
  </b>
  <b>
    <c day="20150219">
      <d>data from day 20150219</d>
      <e>...</e>
    </c>
    <c day="20150221">
      <d>data from day 20150221</d>
      <e>...</e>
    </c>
    <c day="20150223">
      <d>data from day 20150223</d>
      <e>...</e>
    </c>
  </b>
  <!--...-->
</a>

试试这个解决方案。

啊!我懂了。。。我收到了这个错误
错误XPTY0004file:///home/alexis/tmp/a.xsl,在第1行第1列:所需类型为node(),但找到了xs:untypedAtomic。
因为尝试直接从
中访问XML数据失败。现在我明白我做错了什么。啊<代码>键()未定义!它理解
但不理解函数。@Alexiswillke如果你原谅我的法语,那是一个蹩脚的XSLT处理器-
xsl:key
没有
key()
,它是非常无用的。……你确定它一般在
key()
调用时失败吗?还是仅在具有三个参数的XSLT2.0调用上?我将编辑以演示如何使用带有两个参数的函数。是。处理器告诉我该函数根本不存在<代码>中的错误XPST0017file:///home/alexis/tmp/a.xsl,在第1行第39列:没有名为fn:key的函数可用。Ah!我懂了。。。我收到了这个错误
错误XPTY0004file:///home/alexis/tmp/a.xsl,在第1行第1列:所需类型为node(),但找到了xs:untypedAtomic。
因为尝试直接从
中访问XML数据失败。现在我明白我做错了什么。啊<代码>键()未定义!它理解
但不理解函数。@Alexiswillke如果你原谅我的法语,那是一个蹩脚的XSLT处理器-
xsl:key
没有
key()
,它是非常无用的。……你确定它一般在
key()
调用时失败吗?还是仅在具有三个参数的XSLT2.0调用上?我将编辑以演示如何使用带有两个参数的函数。是。处理器告诉我该函数根本不存在<代码>中的错误XPST0017file:///home/alexis/tmp/a.xsl,在第1行第39列:没有名为fn:key的函数可用。