如何使用xsl:number函数访问和计算链接的xml文档中的节点?
我试图瞄准像<xsl:number level="multiple" format="1.1." count="someNode | document(@href)/someOtherNode">
之类的东西,但在'count'函数中,不可能使用'document()'函数。因此,必须有另一种方法来访问存储在其他“.xml”文档中的元素。
修改
据我所知,我必须创建一个我的整个节点结构的临时副本,以获得第一个性能和第二个可读性(当然还有第三个可访问性)。
我的想法:我想将整个嵌套节点树存储在可读变量中。因此,我必须创建一个变量并将所有节点及其内容复制到其中。
这是我想要的文件结构:
<map>
<navref mapref="de-DE/A.2+X000263.ditamap"/>
<navref mapref="en-US/A.2+X000263.ditamap"/>
<navref mapref="es-ES/A.2+X000263.ditamap"/>
</map>
<bookmap id="X000263" xml:lang="de-DE">
<chapter href="A.2+X000264.ditamap"/>
</bookmap>
<map id="X000264" xml:lang="de-DE">
<topicref href="A.2+X000265.ditamap"/>
</map>
<map id="X000265" xml:lang="de-DE">
<topicref href="A.2+X000266.dita"/>
<topicref href="A.2+X000269.dita"/>
<topicref href="A.2+X000267.ditamap"/>
</map>
所有这些文档都包含几个我想要计算和轻松访问的节点(例如,以防止过度使用文档(@ ...)功能。
我开始创建所有内容的临时副本,如下所示:
<xsl:variable name="spine">
<xsl:for-each select="collection('../../?select=*.xml;recursive=yes')">
<xsl:for-each select="//*">
<xsl:copy-of select="current()"/>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
我的目标是找到一个解决方案,它只是以正确的顺序读取所有.xml / .ditamap /.dita文档,并获得所有节点和内容的1:1副本。然后,我可以轻松读取存储的变量节点树,而不必手动遍历所有文档。当然,我可以很容易地计算出特定类型的所有节点。
提前致谢。
答案 0 :(得分:1)
在XSLT 3.0中,您可以在模式中使用doc
函数(count
属性是一种模式),但我怀疑这对您有帮助。
但是由于你省略了select
属性,我假设你在计算上下文节点。除非上下文节点位于您所指的文档中,否则无法对其进行计数,因为该模式必须与当前节点匹配。如果上下文节点已经在您所指的文档中,则可以省略模式中的document
函数(保留模式的其余部分),它将“正常工作”。
如果您试图计算模式无法捕获但需要选择表达式的内容,则应使用count
表达式的组合手动创建数字。由于我不知道你的输入文件,我真的不能举一个例子。
<xsl:for-each select="//*"> <xsl:copy-of select="current()"/> </xsl:for-each>
不要这样做(抱歉粗体;)。这样可以创建每个后代元素的副本。即:
输入:
<root>
<child>
<deeper>
</child>
</root>
将导致这样的输出(注意每个后代如何再次复制):
<root>
<child>
<deeper/>
</child>
</root>
<child>
<deeper/>
</child>
<deeper/>
事实上,沿着这些方向的东西应该足够了(我添加了原始URI,可能有助于调试):
<xsl:variable name="spine">
<xsl:for-each select="collection('../../?select=*.xml;recursive=yes')">
<doc original-href="{base-uri()}">
<!-- assuming you do not need any comments in the root of the document -->
<xsl:copy-of select="/*"/>
</doc>
</xsl:for-each>
</xsl:variable>
如果你不复制,我认为你仍然能得到你想要的东西,但如上所述,你可能需要自己做一些计算。
我没有提到的东西:如果你想要计算来自多个来源的节点,并且它们的元素名称不同,那么只需编写count="someNode | someOtherNode"
就足够了。但是,如果someOtherNode
来自其他文档,则必须确保当前匹配选择的顺序正确。默认情况下,选择多个文档具有实现定义的顺序。
简而言之,我认为您建议的方法很好。我怀疑它是否具有性能优势(因为您正在创建所有内容的副本),但只是让您的解决方案找到时间。
答案 1 :(得分:0)
经过一些研究和Stackoverflow的另一个请求,我得到了一个满足我需求的工作解决方案。以下描述了我现在处理这种情况的方式:
现在我可以根据变量来应用模板
<xsl:apply-templates select="$myVar/document/*"/>
有了这个,我可以轻松访问和计算此单一来源文档中存在的每个节点(据我所知,不可能轻易地计算未组成的节点)单个文件)
答案 2 :(得分:0)
使用DITA-OT(http://www.dita-ot.org/)从根文档(map)制作复合中间文件。 DITA-OT&#34;预处理&#34;和#34; TopicMerge&#34;处理将生成以下结构化合并中间文件:
通常,TOC是由地图结构部分中的样式表通过计算topicref元素层次结构生成的。
从您的示例中,我注意到根映射由navref元素组成。 navref引用将不会从其DITA定义中解析。使用mapref元素而不是navref将解析引用,引用的内容将包含在合并的中间文件中。
这是完成您的要求的最便捷方式。