【问题标题】:Counting figures in xslt在 xslt 中计算数字
【发布时间】:2019-09-19 13:03:23
【问题描述】:

我正在尝试编写一些 xslt 来枚举我的 xml(s!) 中的所有图像

我为此使用了一个密钥,以便我可以稍后在内容中引用图像, 我的问题是我无法弄清楚如何获得一致的价值。 意义: xml 引用了我使用 document() 加载的多个其他文档, 每当我“输入”一个新文档时,键都会被重置,所以在有 2 个图像的文档中我得到两个,在其他的一个

你可以想象

根文档:

<root>
  <chapter href="chapters/doc1.xml"/>
  <chapter href="chapters/doc2.xml"/>
</root> 

doc1.xml

<root>
  <image id="a"/>
  <image id="b"/>
</root> 

doc2.xml

<root>
  <image id="f"/>
</root> 

我在 stackoverflow 上发现了一个旧线程,我认为这有点像我的方向:XSLT: create 'key' across multiple documents? 但我无法让它工作。

目前的工作: 我已经定义了一个键

<xsl:key name="image" match="image" use="@id"/>

我以后会这样使用

 key value for image:<xsl:value-of select="count(key('image', @id)/preceding::image) + 1"/>

这总是会产生上述结果(对于 doc1,我得到“key value for image:1 key value for image:2”bur,对于 doc2,我再次得到“key value for image:1”,在这里我希望得到 3)

为了适应链接的帖子,我尝试使用集合加载所有文档并创建一个新密钥,希望它至少会为我提供所有开始的图像

<xsl:key name="images" match="image" use="all"/>
 <xsl:variable name="location"><xsl:value-of select="$xml-base"/>/chapters?select=*.xml;recurse=yes</xsl:variable>
<xsl:variable name="documents">
  <xsl:value-of select="collection($location)"/>
</xsl:variable>
<xsl:for-each select="collection($location)">
  <xsl:message>
    <xsl:value-of select="./count(key('figure','all'))"/>
  </xsl:message>
</xsl:for-each>

这总是给我 0 我什至不确定在这里使用密钥是否是正确的方法

tldr: 如何跨多个文档枚举 xslt 中的图像?

*编辑,因为我认为这有点不清楚: 我有多个由根 xml 导入的 xml 输入, 它们都可以包含图像 我有一个最终输出文件,需要连续枚举所有图像并能够引用它们

【问题讨论】:

  • 但我无法让它工作。”展示您的尝试,以便我们可以修复它,而不是从头开始。
  • @michael.hor257k 感谢您花时间添加一些上下文

标签: xslt xslt-2.0


【解决方案1】:

最后一个文档有一个image 元素,因此image 没有任何preceding::image

如果您想计算image 元素、count(//image) 用于单个文档或count(document(/root/chapter/@href)//image) 用于在第一个样本上使用document 函数或@987654328,那么也不清楚为什么您需要一个键@ 对于 XSLT 2/3 和 Saxon 9 特定的 collection() 调用应该可以。

&lt;xsl:key name="images" match="image" use="all"/&gt; 是没有意义的,除非任何 image 元素具有名为 all 的子元素。

处理多个文档是可能的,但需要一些额外的努力。如果您需要一般处理并且无法通过模板将所有元素推送到一起以利用 position() 但不知何故需要索引所有这些 image 元素,那么也许执行 &lt;xsl:variable name="images" select="document(/root/chapter/@href)//image"/&gt;&lt;xsl:variable name="image-ids" select="for $img in $images return generate-id($img)"/&gt; 然后简单地使用 &lt;xsl:value-of select="index-of($image-ids, generate-id())"/&gt; in任何xsl:template match="image" 都应该可以工作。

for $img in $images return generate-id($img) 可以在 XSLT 3 中更紧凑地写成$images ! generate-id()

【讨论】:

  • 感谢您的回答,我认为我的问题不够清楚 - 抱歉 - 我不希望有 3 个,我需要 3 个,因为正如我所说,我需要在最后一个单曲中枚举所有图像输出文件它可能是关键是错误的事情,但这也是我提出使用count(document(/root/chapter/@href)//image)i 的建议的一部分,必须计算每个子章节中的所有图像并找到重新枚举的方法因为我希望它不断计数,这是否让我的问题更清楚了
  • @MatthiasG,你能忍受通过使用&lt;xsl:apply-templates select="document(/root/chapter/@href)//image"/&gt; 执行&lt;xsl:template match="image"&gt;&lt;xsl:value-of select="position()"/&gt;...&lt;/xsl:template&gt; 的模板推送document(/root/chapter/@href)//image 吗?如果将它们全部推到一起,如图所示,在模板内部,position() 函数应该在document(/root/chapter/@href)//image 选择的整个image 元素序列中给出当前处理的image 元素的“索引”。跨度>
  • 我在我提供的示例文档中试过了,我很高兴它可以工作,我现在确实有问题将所有其他规则应用于其余内容,有时在之前有时在之后还有其他元素有时会附上这些图像,我现在不知道如何处理这些......这是我误解的概念吗?因为我所做的是创建与元素匹配的模板,并且大多数时候我只使用模板内部 有没有办法将您的方法与这些其他元素一起使用?
  • @MatthiasG,如果在处理所有节点时需要这个数字,那么您需要一种不同的方法,看看编辑中的建议是否有帮助。
猜你喜欢
  • 2021-12-26
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多