gpt4 book ai didi

xml - 使用 XSLT 从 XML 中写入数据列与 Excel 中的行

转载 作者:行者123 更新时间:2023-12-04 20:42:41 25 4
gpt4 key购买 nike

我正在尝试采用下面的 XML 结构(已清理,因此请原谅任何不一致之处)并通过 XSLT 1.0 将其转换为每个 channel 两列的分组列,一列用于开始时间,一列用于节目标题。 XML 看起来像:

<days>
<DAY>
<channel>
<CHANNEL name="A"/>
</channel>
<transmissions>
<TRANSMISSION title="Show 1">
<starttime>
<TIME hours="6" minutes="00" seconds="00" timeinseconds="21600"/>
</starttime>
</TRANSMISSION>
<TRANSMISSION title="Show 2">
<starttime>
<TIME hours="7" minutes="45" seconds="00" timeinseconds="27900"/>
</starttime>
</TRANSMISSION>
<TRANSMISSION title="Show 3">
<starttime>
<TIME hours="8" minutes="00" seconds="00" timeinseconds="28800"/>
</starttime>
</TRANSMISSION>
</transmissions>
<date>
<DATE year="2015" month="3" day="2" dayname="Monday" monthname="March" dateindays="41698"/>
</date>
</DAY>
<DAY>
<channel>
<CHANNEL name="B"/>
</channel>
<transmissions>
<TRANSMISSION title="Show 1">
<starttime>
<TIME hours="6" minutes="00" seconds="00" timeinseconds="21600"/>
</starttime>
</TRANSMISSION>
<TRANSMISSION title="Show 4">
<starttime>
<TIME hours="7" minutes="45" seconds="00" timeinseconds="27900"/>
</starttime>
</TRANSMISSION>
<TRANSMISSION title="Show 2">
<starttime>
<TIME hours="8" minutes="00" seconds="00" timeinseconds="28800"/>
</starttime>
</TRANSMISSION>
</transmissions>
<date>
<DATE year="2015" month="3" day="2" dayname="Monday" monthname="March" dateindays="41698"/>
</date>
</DAY>
</days>

从这段代码中,我需要创建一个 Excel 文档,每个 channel 有两列,一列是开始时间,另一列是传输的标题。这些需要并排(我会发布一张图片,但我没有足够的声誉)。

我试图针对 TRANSMISSION 构建一个 for-each,但这当然意味着第二个 channel 被忽略,直到第一个 channel 传输完成,这会在 channel A 的第 2 行和 channel B 的第 3 行中创建数据,而不是数据两个 channel 都在第 2 行。
<xsl:for-each select="DAY/transmissions/TRANSMISSION">
<xsl:sort select="starttime/TIME/@durationinseconds" data-type="number" order="ascending"/>
<Row ss:AutoFitHeight="0" ss:Height="29.25">
<xsl:if test="../../channel/CHANNEL/@name = 'A'">
<xsl:variable name="time">
<xsl:value-of select="starttime/TIME/@timeinseconds"/>
</xsl:variable>
<Cell>
<Data ss:Type="String">
<xsl:apply-templates select="starttime/TIME" mode="time"/>
</Data>
</Cell>
<Cell ss:StyleID="s17">
<Data ss:Type="String">
<xsl:apply-templates select="../TRANSMISSION[starttime/TIME/@timeinseconds = $time]"/>
</Data>
</Cell>
</xsl:if>
<xsl:if test="../../channel/CHANNEL/@name = 'B'"> (repeat of above)

我意识到这段代码有多个问题,但核心问题是我在处理这段代码中的其他较小问题之前试图解决的问题。

实际上,我需要一次写一列而不是一行,但这当然是不可能的。如何让数据显示为两个分组的数据列,其中每个 channel 都有一个开始时间列表和相关的节目标题?

我考虑过创建一个“主”表,然后使用引用公式来提取信息,但是完整报告将提取的每个 channel 的数据量和数据的可变性会导致如何构建“子”表的问题。更不用说最终用户不喜欢这个解决方案。

我还尝试针对 DAY 节点构建 for-each,但这会在切换到 channel B 之前构建整个 channel A 数据,从而加剧了问题。

最佳答案

此样式表可能是您尝试做的事情的起点:

XSLT 1.0

<!-- (I needed a starting point, you will probably have something different) -->
<xsl:template match="/">
<wrapperElement>
<!-- create the rows -->
<xsl:apply-templates select="//DAY[1]//TRANSMISSION" mode="createRow"/>
</wrapperElement>
</xsl:template>

<!-- template to create the row -->
<xsl:template match="TRANSMISSION" mode="createRow">
<Row ss:AutoFitHeight="0" ss:Height="29.25">
<xsl:apply-templates select="." mode="createCells"/>
</Row>
</xsl:template>

<!-- template to create two cells for each channel -->
<xsl:template match="TRANSMISSION" mode="createCells">
<Cell>
<Data ss:Type="String">
<xsl:apply-templates select="starttime/TIME" mode="time"/>
</Data>
</Cell>
<Cell ss:StyleID="s17">
<Data ss:Type="String">
<xsl:apply-templates select="@title"/>
</Data>
</Cell>
<!-- cells for next channel -->
<xsl:apply-templates select="ancestor::DAY/following-sibling::DAY[1]//TRANSMISSION[count(preceding-sibling::TRANSMISSION) = count(current()/preceding-sibling::TRANSMISSION)]" mode="createCells"/>
</xsl:template>

值得注意的点:
  • 每个 TRANSMISSION 的元素第一个 channel 匹配创建 Row
  • 相同的元素由另一个模板(在不同的 mode 中)处理以生成两个 Cell s 与时间和标题
  • 然后 TRANSMISSION下一个 channel 的元素同位置被处理以创建其他 Cell s 在同一个 Row
  • 关于xml - 使用 XSLT 从 XML 中写入数据列与 Excel 中的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29829627/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com