我们的一家供应商将他们的信息存储在几乎链接列表样式的XML代码中。我一直难以想出一种遍历和连接所有数据的方法。以下是XML代码:
<bibliographic-data>
<reference>
<document-id>
<doc-number>15492293</doc-number>
</document-id>
</reference>
</bibliographic-data>
<related-documents>
<divider>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>09861196</doc-number>
<date>20010518</date>
</document-id>
<parent-document>
<document-id>
<code>UC</code>
<doc-number>6514193</doc-number>
<date>20030204</date>
</document-id>
</parent-document>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>10665793</doc-number>
</document-id>
</child-doc>
</relation>
</divider>
<paperback>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>14711658</doc-number>
<date>20150513</date>
</document-id>
<parent-status>SHELVED</parent-status>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>15492293</doc-number>
</document-id>
</child-doc>
</relation>
</paperback>
<paperback>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>14473159</doc-number>
<date>20140829</date>
</document-id>
<parent-document>
<document-id>
<code>UC</code>
<doc-number>9636401</doc-number>
<date>20170502</date>
</document-id>
</parent-document>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>14711658</doc-number>
</document-id>
</child-doc>
</relation>
</paperback>
<paperback>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>12823700</doc-number>
<date>20100625</date>
</document-id>
<parent-document>
<document-id>
<code>UC</code>
<doc-number>8470294</doc-number>
<date>20130625</date>
</document-id>
</parent-document>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>13911616</doc-number>
</document-id>
</child-doc>
</relation>
</paperback>
<paperback>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>10665793</doc-number>
<date>20030919</date>
</document-id>
<parent-document>
<document-id>
<code>UC</code>
<doc-number>7776310</doc-number>
<date>20100817</date>
</document-id>
</parent-document>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>12823700</doc-number>
</document-id>
</child-doc>
</relation>
</paperback>
<hardcover>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>13911616</doc-number>
<date>20130613</date>
</document-id>
<parent-document>
<document-id>
<code>UC</code>
<doc-number>8821835</doc-number>
<date>20140902</date>
</document-id>
</parent-document>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>14473159</doc-number>
</document-id>
</child-doc>
</relation>
</hardcover>
<hardcover>
<relation>
<parent-doc>
<document-id>
<code>UC</code>
<doc-number>09861326</doc-number>
<date>20010518</date>
</document-id>
<parent-document>
<document-id>
<code>UC</code>
<doc-number>6746661</doc-number>
<date>20040608</date>
</document-id>
</parent-document>
</parent-doc>
<child-doc>
<document-id>
<code>UC</code>
<doc-number>09861196</doc-number>
</document-id>
</child-doc>
</relation>
</hardcover>
</related-documents>
我正在尝试使用子级和父级doc-number字段遍历所有节点。它应该连接15492293应该启动链后跟14711658 - &gt; 14473159 - &gt; 13911616 - &gt; 12823700 - &gt; 10665793 - &gt; 09861196 - &gt; 09861326
我试图使用以下XPAth表达式:
for $ i in(./divider,。/ paperback,。/ drcover)
[relation / child-doc / document-id / doc-number = / bibliographic-data / reference / document-id / doc-number]
返回
$ $ f $
返回
$ f [relation / child-doc / document-id / doc-number = $ i / relation / parent-doc / document-id / doc-number]
遍历多个祖先几乎链接列表样式的节点的优雅方式是什么。任何帮助都会有所帮助。我可以根据要求提供进一步的解释。
答案 0 :(得分:0)
我认为您可以在引用后编写递归函数,最好使用密钥完成:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="3.0">
<xsl:param name="start-id">15492293</xsl:param>
<xsl:output method="text"/>
<xsl:key name="parent" match="related-documents/*" use="relation/child-doc/document-id/doc-number"/>
<xsl:function name="mf:get-ancestor-ids" as="xs:integer*">
<xsl:param name="item" as="element()"/>
<xsl:sequence
select="let $parent-id := $item/relation/parent-doc/document-id/doc-number,
$parent := key('parent', $parent-id, root($item))
return (xs:integer($parent-id), $parent!mf:get-ancestor-ids(.))"/>
</xsl:function>
<xsl:template match="/" name="xsl:initial-template">
<xsl:value-of select="$start-id, mf:get-ancestor-ids(key('parent', $start-id))" separator=" -> "/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/eiZQaF1给出了结果
15492293 -> 14711658 -> 14473159 -> 13911616 -> 12823700 -> 10665793 -> 9861196 -> 9861326
该示例使用了一些XSLT和XPath 3功能,例如let
或!
,但您当然可以使用xsl:variable
而不是let
为XSLT和XPath 2.0重写该功能$parent/mf:get-ancestor-ids(.)
的{{1}}或if ($parent) then mf:get-ancestor-ids($parent) else ()
:
$parent!mf:get-ancestor-ids(.)