首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在XSLT中递归应用模板时出现的问题

在XSLT中递归应用模板时出现的问题
EN

Stack Overflow用户
提问于 2015-01-09 08:24:35
回答 1查看 248关注 0票数 0

我对XPath和XSLT很陌生。我正在编写一个XSLT,每当它在输入中发现“complexType”作为类型属性时,它就会递归地应用模板。

请注意,识别复杂类型的逻辑很好,所以我不介意。

下面是我的输入:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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>

解释以下流程:

  1. XSLT开始从root读取输入。
  2. 创建对象元素,然后应用另一个模板(ComplexTypeTemplate),其名称为Object1。
  3. ComplexType模板执行一些逻辑来将complexType标识为类型属性,然后调用另一个名为“Element”的模板。
  4. 元素模板再次调用complexType模板,以便为complexType类型应用相同的逻辑。

第四步不是为我工作。我相信这其中存在一些XPath模式或路径问题。

EN

回答 1

Stack Overflow用户

发布于 2015-01-09 08:44:02

您的主要问题出现在这一行中:

代码语言:javascript
复制
<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 )

代码语言:javascript
复制
<xsl:template name="Elements">
    <xsl:for-each select="*/*:element">
        <xsl:apply-templates select="//*:complexType[@name = current()/@type]" />
    </xsl:for-each>
</xsl:template>

不过,最好取消命名模板,而使用模板匹配。试试这个XSLT

试试这个XSLT

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27856432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档