是否可以使用XSLT2.0将节省的XML转换为完整的HTML表?
非常重要的一点:我使用的是QtXmlPattern(一个未完全实现的XSLT2.0处理器,在实现过程中有一些bug…) 我有一个格式良好的XML文件,其中的数据定义在四级数组中,如下所示:是否可以使用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">
<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的函数可用。