我需要将一些(未指定的)嵌套导入的XSD收集到一个临时树变量中。转换从schema_1.xsd开始,后者又导入其他几个XSD。
像这样:schema_1.xsd的内容:
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<import namespace="http://www.someplace.com" schemaLocation="schema_2.xsd"/>
<import namespace="http://www.someplace.com" schemaLocation="schema_3.xsd"/>
<element name="TopElement1">
<complexType>
<sequence>
<element name="ChildElement1"/>
<element name="ChildElement2"/>
<element name="ChildElement3"/>
</sequence>
</complexType>
</element>
</schema>
和schema_2.xsd的内容:
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<import namespace="http://www.someplace.com" schemaLocation="schema_3.xsd"/>
<import namespace="http://www.someplace.com" schemaLocation="schema_4.xsd"/>
<element name="TopElement2">
<complexType>
<sequence>
<element name="ChildElement4" minOccurs="0"/>
<element name="ChildElement5"/>
</sequence>
</complexType>
</element>
</schema>
依此类推(我想包括第三个XSD有点多余?)。
我需要做的是构建一个包含所有嵌套XSD中所有节点的整个临时树,包括第一个XSD的内容,即schema_1.xsd。从XSD可以看出,一些导入可能会发生两次。优选地,任何模式应该仅被复制到期望的变量一次。更糟糕的是,我知道可能存在循环引用,这显然会对解决方案空间产生进一步的限制。
我需要在XSLT中的变量中访问生成的临时树。也许是这样:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:variable name="root">
<!-- magic -->
</xsl:variable>
<xsl:template match="/">
<!-- processing $root/fullStructure -->
</xsl:template>
</xsl:stylesheet>
$ root的实际内容我想看起来像这样:
<fullStructure>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<import namespace="http://www.someplace.com" schemaLocation="schema_2.xsd"/>
<import namespace="http://www.someplace.com" schemaLocation="schema_3.xsd"/>
<element name="TopElement1">
<complexType>
<sequence>
<element name="ChildElement1"/>
<element name="ChildElement2"/>
<element name="ChildElement3"/>
</sequence>
</complexType>
</element>
</schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<import namespace="http://www.someplace.com" schemaLocation="schema_3.xsd"/>
<import namespace="http://www.someplace.com" schemaLocation="schema_4.xsd"/>
<element name="TopElement2">
<complexType>
<sequence>
<element name="ChildElement4" minOccurs="0"/>
<element name="ChildElement5"/>
</sequence>
</complexType>
</element>
</schema>
<!-- copy-of for schema_3.xsd and schema_4.xsd is omitted for the sake of brevity. -->
</fullStructure>
此树的大小仅受导入数量和可用计算资源的限制。当然,导入节点不再是必需的,但是,它们也没有问题,所以盲目复制完全没问题。
重大更新
根据Dimitre Novatchev的要求,我已经包含了几个有效的XSD,以及对所需结果的描述。另外,我删除了一些多余的评论。由于LarsH的反馈,我也做了一些小的更新。
有人可以给我指向正确的方向吗?万分感谢!
答案 0 :(得分:2)
此样式表:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:local="http://localhost"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="local xs">
<xsl:template match="/">
<fullStructure>
<xsl:copy-of select="local:explode(.)"/>
</fullStructure>
</xsl:template>
<xsl:function name="local:explode" as="node()*">
<xsl:param name="pNodes" as="node()*"/>
<xsl:sequence select="local:explode($pNodes/root(.),())"/>
</xsl:function>
<xsl:function name="local:explode" as="node()*">
<xsl:param name="pTodo" as="node()*"/>
<xsl:param name="pDone" as="node()*"/>
<xsl:sequence
select="if (empty($pTodo))
then $pDone
else local:explode(
document(
($pTodo except $pDone)
/xs:schema/xs:import/@schemaLocation
),
$pTodo | $pDone
)"/>
</xsl:function>
</xsl:stylesheet>
使用此输入:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<import namespace="http://www.someplace.com"
schemaLocation="schema2.xsd"/>
<element name="TopElement1">
<complexType>
<sequence>
<element name="ChildElement1"/>
<element name="ChildElement2"/>
<element name="ChildElement3"/>
</sequence>
</complexType>
</element>
</schema>
这个schema2.xsd
文件:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<element name="TopElement2">
<complexType>
<sequence>
<element name="ChildElement4" minOccurs="0"/>
<element name="ChildElement5"/>
</sequence>
</complexType>
</element>
</schema>
输出:
<fullStructure>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<import namespace="http://www.someplace.com"
schemaLocation="schema2.xsd"/>
<element name="TopElement1">
<complexType>
<sequence>
<element name="ChildElement1"/>
<element name="ChildElement2"/>
<element name="ChildElement3"/>
</sequence>
</complexType>
</element>
</schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd">
<element name="TopElement2">
<complexType>
<sequence>
<element name="ChildElement4" minOccurs="0"/>
<element name="ChildElement5"/>
</sequence>
</complexType>
</element>
</schema>
</fullStructure>