我是XPath和XSLT的新手。我正在编写一个XSLT,它在输入中找到任何'complexType'作为type属性时递归地应用模板。
请注意,识别复杂类型的逻辑工作正常,所以我不会为此烦恼。
下面是我的XML Schema输入:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Object1">
<xs:all>
<xs:element minOccurs="0" name="segment-1" type="xs:string" />
<xs:element minOccurs="0" name="segment-2" type="xs:string" />
<xs:element minOccurs="0" name="complexType1" type="anyComplexType" />
</xs:all>
</xs:complexType>
<xs:complexType name="anyComplexType">
<xs:all>
<xs:element minOccurs="0" name="complexType2" type="anotherComplexType" />
</xs:all>
</xs:complexType>
<xs:complexType name="anyComplexType">
<xs:all>
<some Element>
</xs:all>
</xs:complexType>
</xs:schema>
这是XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.approuter.com/schemas/cdk/api/">
<xsl:output indent="yes" xml:space="preserve" method="xml" />
<xsl:variable name="ObjectType" select=" 'Object1' " />
<xsl:template match="/">
<xsl:element name="object">
<xsl:attribute name="name" select="$ObjectType" />
<xsl:attribute name="label" select="$ObjectType" />
<xsl:attribute name="minCount">1</xsl:attribute>
<xsl:attribute name="maxCount">1</xsl:attribute>
<xsl:apply-templates select="//*:complexType[@name = $ObjectType]" />
</xsl:element>
</xsl:template>
<xsl:template match="*:complexType">
<!-- Logic to fing complexType' goes here -->
<xsl:call-template name="Elements" />
</xsl:template>
<xsl:template name="Elements">
<xsl:apply-templates select="//*:complexType[@name =@type]" />
</xsl:template>
</xsl:stylesheet>
解释以下流程:
第4步对我不起作用。我相信这里有一些XPath模式或路径问题。
答案 0 :(得分:1)
您的主要问题出现在这一行:
<xsl:apply-templates select="//*:complexType[@name = @type]" />
您正在寻找其xs:complexType
属性与其自己的name
属性匹配的任何@type
。但是,没有xs:complexType
元素甚至具有type
属性。
xs:element
具有type
属性,但当您执行xsl:apply-templates
时,您位于xs:complexType
元素上。调用命名模板不会改变您的上下文。
要解决此问题,您可以更改命名模板Elements
以包含用于选择element
元素的代码。您还需要使用current()
函数来引用您当前的上下文(element
而不是您要选择的complexType
<xsl:template name="Elements">
<xsl:for-each select="*/*:element">
<xsl:apply-templates select="//*:complexType[@name = current()/@type]" />
</xsl:for-each>
</xsl:template>
最好不要使用命名模板,而是使用模板匹配。试试这个XSLT
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.approuter.com/schemas/cdk/api/">
<xsl:output indent="yes" xml:space="preserve" method="xml" />
<xsl:variable name="ObjectType" select=" 'Object1' " />
<xsl:template match="/">
<xsl:element name="object">
<xsl:attribute name="name" select="$ObjectType" />
<xsl:attribute name="label" select="$ObjectType" />
<xsl:attribute name="minCount">1</xsl:attribute>
<xsl:attribute name="maxCount">1</xsl:attribute>
<xsl:apply-templates select="//*:complexType[@name = $ObjectType]" />
</xsl:element>
</xsl:template>
<xsl:template match="*:complexType">
<xsl:value-of select="@name" />
<xsl:apply-templates select="*/*:element" />
</xsl:template>
<xsl:template match="*:element">
<xsl:apply-templates select="//*:complexType[@name = current()/@type]" />
</xsl:template>
</xsl:stylesheet>
请注意,使用xsl:key
查找complexType
记录实际上可能更好。也试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.approuter.com/schemas/cdk/api/">
<xsl:output indent="yes" xml:space="preserve" method="xml" />
<xsl:key name="complexType" match="*:complexType" use="@name" />
<xsl:variable name="ObjectType" select=" 'Object1' " />
<xsl:template match="/">
<xsl:element name="object">
<xsl:attribute name="name" select="$ObjectType" />
<xsl:attribute name="label" select="$ObjectType" />
<xsl:attribute name="minCount">1</xsl:attribute>
<xsl:attribute name="maxCount">1</xsl:attribute>
<xsl:apply-templates select="key('complexType', $ObjectType)" />
</xsl:element>
</xsl:template>
<xsl:template match="*:complexType">
<xsl:value-of select="@name" />
<xsl:apply-templates select="*/*:element" />
</xsl:template>
<xsl:template match="*:element">
<xsl:apply-templates select="key('complexType', @type)" />
</xsl:template>
</xsl:stylesheet>