外部数据中的 XSL 应用模板
XSL apply-template within external data
我想转换一个 XML 表示 classes 及其基础 classes,classes 包含它自己的方法和属性,加上其所有基 classes 的方法和属性,因为 OO 继承有效。
一个 XML 可以是
<classes>
<class name="A" author="Mr.X" >
<attribute name="i_" type="integer" visibility="protected" />
<attribute name="f_" type="float" visibility="private" />
<attribute name="c_" type="char" visibility="private" />
<method name="foo" return="integer" visibility="public" >
<param name="a" type="integer" />
<param name="b" type="integer" />
</method>
</class>
<class name="B" author="Mr.Y" >
<attribute name="s_" type="string" visibility="protected" />
<method name="bar" visibility="public" />
</class>
<class name="CA" author="Mr.Z" base="A" >
<attribute name="d_" type="double" visibility="protected" />
</class>
<class name="CB" author="Mr.Z" base="B" />
<class name="DCA" author="Mr.X" base="CA" >
<attribute name="s_" type="string" visibility="protected" />
</class>
</classes>
应该转化为
<classes>
<class name="A" author="Mr.X">
<attribute name="i_" type="integer" visibility="protected"/>
<attribute name="f_" type="float" visibility="private"/>
<attribute name="c_" type="char" visibility="private"/>
<method name="foo" return="integer" visibility="public">
<param name="a" type="integer"/>
<param name="b" type="integer"/>
</method>
</class>
<class name="B" author="Mr.Y">
<attribute name="s_" type="string" visibility="protected"/>
<method name="bar" visibility="public"/>
</class>
<class name="CA" author="Mr.Z">
<attribute name="d_" type="double" visibility="protected"/>
<!--[begin] inherited from class A by Mr.X-->
<attribute name="i_" type="integer" visibility="protected"/>
<attribute name="f_" type="float" visibility="private"/>
<attribute name="c_" type="char" visibility="private"/>
<method name="foo" return="integer" visibility="public">
<param name="a" type="integer"/>
<param name="b" type="integer"/>
</method>
<!--[end] inherited from class A-->
</class>
<class name="CB" author="Mr.Z">
<!--[begin] inherited from class B by Mr.Y-->
<attribute name="s_" type="string" visibility="protected"/>
<method name="bar" visibility="public"/>
<!--[end] inherited from class B-->
</class>
<class name="DCA" author="Mr.X">
<attribute name="s_" type="string" visibility="protected"/>
<!--[begin] inherited from class CA by Mr.Z-->
<attribute name="d_" type="double" visibility="protected"/>
<!--[begin] inherited from class A by Mr.X-->
<attribute name="i_" type="integer" visibility="protected"/>
<attribute name="f_" type="float" visibility="private"/>
<attribute name="c_" type="char" visibility="private"/>
<method name="foo" return="integer" visibility="public">
<param name="a" type="integer"/>
<param name="b" type="integer"/>
</method>
<!--[end] inherited from class A-->
<!--[end] inherited from class CA-->
</class>
</classes>
在 Michael 的帮助下,如果所有 classes 都在同一个 XML 文件中定义,我有以下 XSL 可以正常工作。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="parent" match="class" use="@name" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
或以下等效但没有键的转换。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
现在,我想处理这些 classes 可以在主 xml 或其他 XML 文件中定义,并与其他文件链接一个导入元素,这意味着外部 XML 可以像写在主 XML.
中一样使用
代表这些 class 的简化 XML 可以是
<classes>
<import file="c2.xml" />
<class name="XZ" author="Mr.B" base="Z">
<method name="foo" visibility="public" />
</class>
</classes>
c2.xml 的内容可能是
<classes>
<class name="Z" author="Mr.A" >
<attribute name="i_" type="integer" visibility="protected" />
</class>
</classes>
预期输出为
<classes>
<class name="Z" author="Mr.A">
<attribute name="i_" type="integer" visibility="protected"/>
</class>
<class name="XZ" author="Mr.B">
<method name="foo" visibility="public"/>
<!--[begin] inherited from class Z by Mr.A-->
<attribute name="i_" type="integer" visibility="protected"/>
<!--[end] inherited from class Z-->
</class>
</classes>
新的 XSL 与上面的非常相似,但添加了以下模式,以处理新元素
<xsl:template match="/classes/import">
<xsl:comment>
<xsl:text>importing </xsl:text>
<xsl:value-of select="@file"/>
<xsl:text> file</xsl:text>
</xsl:comment>
<xsl:apply-templates select="document(@file)/classes/node()" />
</xsl:template>
因此,使用键时,XSL 将如下所示
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="parent" match="class" use="@name" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/classes/import">
<xsl:comment>
<xsl:text>importing </xsl:text>
<xsl:value-of select="@file"/>
<xsl:text> file</xsl:text>
</xsl:comment>
<xsl:apply-templates select="document(@file)/classes/node()" />
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
或者像下面没有使用键的那个
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/classes/import">
<xsl:comment>
<xsl:text>importing </xsl:text>
<xsl:value-of select="@file"/>
<xsl:text> file</xsl:text>
</xsl:comment>
<xsl:apply-templates select="document(@file)/classes/node()" />
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
与导入元素关联的转换适用于外部文件中定义的 classes,但基础 class 继承行为不适用于那些 classes。
上述 XSL 和之前的 XML(包含 c2.xml 文件的那个)的(错误)输出是
<classes>
<!--importing c2.xml file-->
<class name="Z" author="Mr.A">
<attribute name="i_" type="integer" visibility="protected"/>
</class>
<class name="XZ" author="Mr.B">
<method name="foo" visibility="public"/>
</class>
</classes>
请注意,XZ class 不包含其基础 class Z
中的方法和属性
请注意,外部 xml 文件也可能包含导入元素
我尝试了两种不同的方法。第一个是为 classes 使用密钥,包括那些在外部 XML 文件中声明的密钥。我失败了,因为我事先不知道外部文件名,无法为这些外部 XML 文件中定义的 classes 生成密钥。第二个是应用 "inherit" 模式谓词,但我又失败了,因为我不知道外部文件名,无法为所有文件应用具有继承模式的模板 class。
任何有关如何从外部数据为 classes 应用 "inherit" 模板的帮助,将不胜感激。任何方法,有或没有钥匙,对我来说都很好。
提前致谢。
键只能在单个文档中使用。我建议两种方法:
(a) 首先将所有文档合并为一个,然后使用您当前的解决方案。
(b) 不使用键,而是以 XSLT 3.0 映射的形式构建跨文档索引。像这样:
<xsl:mode name="index" on-no-match="shallow-skip"/>
<xsl:variable name="globalIndex" as="map(xs:string, element(*))">
<xsl:map>
<xsl:apply-templates mode="index"/>
</xsl:map>
</xsl:variable>
<xsl:template match="class" mode="index">
<xsl:map-entry key="@name" select="."/>
<xsl:apply-templates mode="index"/>
</xsl:template>
<xsl:template match="import" mode="index">
<xsl:apply-templates select="doc(@file)" mode="index"/>
</xsl:template>
然后在您之前使用 key('parent', @base)
的地方,您现在可以使用 $globalIndex(@base)
。
(c) 这个解决方案不会给你键或映射的速度,除非你的处理器有一个智能优化器(比如 Saxon-EE)自动索引事物;但它只使用 XSLT 2.0:
<xsl:variable name="allClasses" as="element(class)*">
<xsl:apply-templates mode="index"/>
</xsl:variable>
<xsl:template match="class" mode="index">
<xsl:sequence select="."/>
<xsl:apply-templates mode="index"/>
</xsl:template>
<xsl:template match="import" mode="index">
<xsl:apply-templates select="doc(@file)" mode="index"/>
</xsl:template>
<xsl:template match="node()" mode="index">
<xsl:apply-templates mode="index"/>
</xsl:template>
然后在您之前使用 key('parent', @base)
的地方,您现在可以使用 $allClasses[@name=current()/@base]
。
我想转换一个 XML 表示 classes 及其基础 classes,classes 包含它自己的方法和属性,加上其所有基 classes 的方法和属性,因为 OO 继承有效。
一个 XML 可以是
<classes>
<class name="A" author="Mr.X" >
<attribute name="i_" type="integer" visibility="protected" />
<attribute name="f_" type="float" visibility="private" />
<attribute name="c_" type="char" visibility="private" />
<method name="foo" return="integer" visibility="public" >
<param name="a" type="integer" />
<param name="b" type="integer" />
</method>
</class>
<class name="B" author="Mr.Y" >
<attribute name="s_" type="string" visibility="protected" />
<method name="bar" visibility="public" />
</class>
<class name="CA" author="Mr.Z" base="A" >
<attribute name="d_" type="double" visibility="protected" />
</class>
<class name="CB" author="Mr.Z" base="B" />
<class name="DCA" author="Mr.X" base="CA" >
<attribute name="s_" type="string" visibility="protected" />
</class>
</classes>
应该转化为
<classes>
<class name="A" author="Mr.X">
<attribute name="i_" type="integer" visibility="protected"/>
<attribute name="f_" type="float" visibility="private"/>
<attribute name="c_" type="char" visibility="private"/>
<method name="foo" return="integer" visibility="public">
<param name="a" type="integer"/>
<param name="b" type="integer"/>
</method>
</class>
<class name="B" author="Mr.Y">
<attribute name="s_" type="string" visibility="protected"/>
<method name="bar" visibility="public"/>
</class>
<class name="CA" author="Mr.Z">
<attribute name="d_" type="double" visibility="protected"/>
<!--[begin] inherited from class A by Mr.X-->
<attribute name="i_" type="integer" visibility="protected"/>
<attribute name="f_" type="float" visibility="private"/>
<attribute name="c_" type="char" visibility="private"/>
<method name="foo" return="integer" visibility="public">
<param name="a" type="integer"/>
<param name="b" type="integer"/>
</method>
<!--[end] inherited from class A-->
</class>
<class name="CB" author="Mr.Z">
<!--[begin] inherited from class B by Mr.Y-->
<attribute name="s_" type="string" visibility="protected"/>
<method name="bar" visibility="public"/>
<!--[end] inherited from class B-->
</class>
<class name="DCA" author="Mr.X">
<attribute name="s_" type="string" visibility="protected"/>
<!--[begin] inherited from class CA by Mr.Z-->
<attribute name="d_" type="double" visibility="protected"/>
<!--[begin] inherited from class A by Mr.X-->
<attribute name="i_" type="integer" visibility="protected"/>
<attribute name="f_" type="float" visibility="private"/>
<attribute name="c_" type="char" visibility="private"/>
<method name="foo" return="integer" visibility="public">
<param name="a" type="integer"/>
<param name="b" type="integer"/>
</method>
<!--[end] inherited from class A-->
<!--[end] inherited from class CA-->
</class>
</classes>
在 Michael 的帮助下,如果所有 classes 都在同一个 XML 文件中定义,我有以下 XSL 可以正常工作。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="parent" match="class" use="@name" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
或以下等效但没有键的转换。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
现在,我想处理这些 classes 可以在主 xml 或其他 XML 文件中定义,并与其他文件链接一个导入元素,这意味着外部 XML 可以像写在主 XML.
中一样使用代表这些 class 的简化 XML 可以是
<classes>
<import file="c2.xml" />
<class name="XZ" author="Mr.B" base="Z">
<method name="foo" visibility="public" />
</class>
</classes>
c2.xml 的内容可能是
<classes>
<class name="Z" author="Mr.A" >
<attribute name="i_" type="integer" visibility="protected" />
</class>
</classes>
预期输出为
<classes>
<class name="Z" author="Mr.A">
<attribute name="i_" type="integer" visibility="protected"/>
</class>
<class name="XZ" author="Mr.B">
<method name="foo" visibility="public"/>
<!--[begin] inherited from class Z by Mr.A-->
<attribute name="i_" type="integer" visibility="protected"/>
<!--[end] inherited from class Z-->
</class>
</classes>
新的 XSL 与上面的非常相似,但添加了以下模式,以处理新元素
<xsl:template match="/classes/import">
<xsl:comment>
<xsl:text>importing </xsl:text>
<xsl:value-of select="@file"/>
<xsl:text> file</xsl:text>
</xsl:comment>
<xsl:apply-templates select="document(@file)/classes/node()" />
</xsl:template>
因此,使用键时,XSL 将如下所示
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="parent" match="class" use="@name" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/classes/import">
<xsl:comment>
<xsl:text>importing </xsl:text>
<xsl:value-of select="@file"/>
<xsl:text> file</xsl:text>
</xsl:comment>
<xsl:apply-templates select="document(@file)/classes/node()" />
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="key('parent', @base)" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
或者像下面没有使用键的那个
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/classes/import">
<xsl:comment>
<xsl:text>importing </xsl:text>
<xsl:value-of select="@file"/>
<xsl:text> file</xsl:text>
</xsl:comment>
<xsl:apply-templates select="document(@file)/classes/node()" />
</xsl:template>
<xsl:template match="class">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='base']|node()"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
</xsl:copy>
</xsl:template>
<xsl:template match="class" mode="inherit">
<xsl:comment>
<xsl:text>[begin] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> by </xsl:text>
<xsl:value-of select="@author"/>
</xsl:comment>
<xsl:copy-of select="attribute | method"/>
<xsl:apply-templates select="//class[@name=current()/@base]" mode="inherit"/>
<xsl:comment>
<xsl:text>[end] inherited from class </xsl:text>
<xsl:value-of select="@name"/>
</xsl:comment>
</xsl:template>
</xsl:stylesheet>
与导入元素关联的转换适用于外部文件中定义的 classes,但基础 class 继承行为不适用于那些 classes。
上述 XSL 和之前的 XML(包含 c2.xml 文件的那个)的(错误)输出是
<classes>
<!--importing c2.xml file-->
<class name="Z" author="Mr.A">
<attribute name="i_" type="integer" visibility="protected"/>
</class>
<class name="XZ" author="Mr.B">
<method name="foo" visibility="public"/>
</class>
</classes>
请注意,XZ class 不包含其基础 class Z
中的方法和属性请注意,外部 xml 文件也可能包含导入元素
我尝试了两种不同的方法。第一个是为 classes 使用密钥,包括那些在外部 XML 文件中声明的密钥。我失败了,因为我事先不知道外部文件名,无法为这些外部 XML 文件中定义的 classes 生成密钥。第二个是应用 "inherit" 模式谓词,但我又失败了,因为我不知道外部文件名,无法为所有文件应用具有继承模式的模板 class。
任何有关如何从外部数据为 classes 应用 "inherit" 模板的帮助,将不胜感激。任何方法,有或没有钥匙,对我来说都很好。
提前致谢。
键只能在单个文档中使用。我建议两种方法:
(a) 首先将所有文档合并为一个,然后使用您当前的解决方案。
(b) 不使用键,而是以 XSLT 3.0 映射的形式构建跨文档索引。像这样:
<xsl:mode name="index" on-no-match="shallow-skip"/>
<xsl:variable name="globalIndex" as="map(xs:string, element(*))">
<xsl:map>
<xsl:apply-templates mode="index"/>
</xsl:map>
</xsl:variable>
<xsl:template match="class" mode="index">
<xsl:map-entry key="@name" select="."/>
<xsl:apply-templates mode="index"/>
</xsl:template>
<xsl:template match="import" mode="index">
<xsl:apply-templates select="doc(@file)" mode="index"/>
</xsl:template>
然后在您之前使用 key('parent', @base)
的地方,您现在可以使用 $globalIndex(@base)
。
(c) 这个解决方案不会给你键或映射的速度,除非你的处理器有一个智能优化器(比如 Saxon-EE)自动索引事物;但它只使用 XSLT 2.0:
<xsl:variable name="allClasses" as="element(class)*">
<xsl:apply-templates mode="index"/>
</xsl:variable>
<xsl:template match="class" mode="index">
<xsl:sequence select="."/>
<xsl:apply-templates mode="index"/>
</xsl:template>
<xsl:template match="import" mode="index">
<xsl:apply-templates select="doc(@file)" mode="index"/>
</xsl:template>
<xsl:template match="node()" mode="index">
<xsl:apply-templates mode="index"/>
</xsl:template>
然后在您之前使用 key('parent', @base)
的地方,您现在可以使用 $allClasses[@name=current()/@base]
。