XSLT:在最后一个simpleType之后和第一个complexType之前将元素定义添加到XSD中

时间:2013-03-21 16:21:18

标签: xsd xslt-2.0

我正在尝试创建一个XSLT 2.0样式表,它将我的XSD转换为相同的XSD,但扩展了一些额外的元素。我试图在声明的最后一个simpleType之后和第一个包含属性myAtt的complexType之前添加一个元素(如果有复数,否则在最后一个simpleType之后)

MyXSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.myspace.com/myxsd" targetNamespace="http://www.myspace.com/myxsd" elementFormDefault="qualified">
    <xs:include schemaLocation="myxsd-simpletypes.xsd"/>
    <xs:element name="myComplexTypeA" type="myComplexTypeAType"/>
    <xs:complexType name="myXmlType">
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
            <xs:element name="myComplexTypeB" type="myComplexTypeBType">
                <xs:annotation>
                    <xs:documentation>My first complex type</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myComplexTypeBType">
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
            <xs:element name="myComplexTypeC" type="myComplexTypeCType" minOccurs="0" maxOccurs="100"/>
            <xs:element name="myComplexTypeD" type="myComplexTypeDType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myComplexTypeCType">
        <xs:annotation>
            <xs:documentation>Some documentation</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myComplexTypeDType">
        <xs:annotation>
            <xs:documentation>Some documentation</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
</xs:schema>

MyXSLT

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs xdt err fn" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:err="http://www.w3.org/2005/xqt-errors">
    <xsl:output method="xml" indent="yes"/>

    <!-- copy all nodes and attributes-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- For each complexType do this -->
    <xsl:template match="/xs:schema/xs:complexType/xs:sequence">
        <xsl:element name="xs:sequence">
            <xsl:for-each select="xs:element">
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>

                <!-- Only add element after last simpleType and before first complexType (if complexType exists) -->
                <xsl:if test="?????">
                    <xsl:element name="xs:element">
                        <xsl:attribute name="maxOccurs">unbounded</xsl:attribute>
                        <xsl:attribute name="minOccurs">0</xsl:attribute>
                        <xsl:attribute name="name">myAddition</xsl:attribute>
                        <xsl:attribute name="type">myAdditionType</xsl:attribute>
                    </xsl:element>
                </xsl:if>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

    <!-- After last complexType in file add definition of myAddition -->
    <xsl:template match="/xs:schema/xs:complexType[last()]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:element name="xs:complexType">
            <xsl:attribute name="name">myAdditionType</xsl:attribute>
            <xsl:element name="xs:sequence">
                <xsl:element name="xs:element">
                    <xsl:attribute name="minOccurs">0</xsl:attribute>
                    <xsl:attribute name="name">myAdditionA</xsl:attribute>
                    <xsl:attribute name="type">myAdditionAType</xsl:attribute>
                </xsl:element>
                <xsl:element name="xs:element">
                    <xsl:attribute name="minOccurs">0</xsl:attribute>
                    <xsl:attribute name="name">myAdditionBValue</xsl:attribute>
                    <xsl:attribute name="type">myAdditionBType</xsl:attribute>
                </xsl:element>
            </xsl:element>
            <xsl:element name="xs:attribute">
                <xsl:attribute name="fixed">myValue</xsl:attribute>
                <xsl:attribute name="name">myAtt</xsl:attribute>
                <xsl:attribute name="type">stringType</xsl:attribute>
                <xsl:attribute name="use">required</xsl:attribute>
            </xsl:element>
        </xsl:element>
        <xsl:element name="xs:simpleType">
            <xsl:attribute name="name">myAdditionAType</xsl:attribute>
            <xsl:element name="xs:restriction">
                <xsl:attribute name="base">AType</xsl:attribute>
                <xsl:element name="xs:maxLength">
                    <xsl:attribute name="value">10</xsl:attribute>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:element name="xs:simpleType">
            <xsl:attribute name="name">myAdditionBType</xsl:attribute>
            <xsl:element name="xs:restriction">
                <xsl:attribute name="base">AType</xsl:attribute>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

我现在得到的结果: 没有,因为它尚未完成!

通缉结果:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.myspace.com/myxsd" targetNamespace="http://www.myspace.com/myxsd" elementFormDefault="qualified">
    <xs:include schemaLocation="myxsd-simpletypes.xsd"/>
    <xs:element name="myComplexTypeA" type="myComplexTypeAType"/>
    <xs:complexType name="myXmlType">
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
            <xs:element name="myAddition" type="myAdditionType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="myComplexTypeB" type="myComplexTypeBType">
                <xs:annotation>
                    <xs:documentation>My first complex type</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myComplexTypeBType">
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
            <xs:element name="myAddition" type="myAdditionType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="myComplexTypeC" type="myComplexTypeCType" minOccurs="0" maxOccurs="100"/>
            <xs:element name="myComplexTypeD" type="myComplexTypeDType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myComplexTypeCType">
        <xs:annotation>
            <xs:documentation>Some documentation</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
            <xs:element name="myAddition" type="myAdditionType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myComplexTypeDType">
        <xs:annotation>
            <xs:documentation>Some documentation</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="mySimpleTypeA" type="mySimpleTypeAType" minOccurs="0"/>
            <xs:element name="mySimpleTypeB" type="mySimpleTypeBType" minOccurs="0"/>
            <xs:element name="mySimpleTypeC" type="mySimpleTypeCType" minOccurs="0"/>
            <xs:element name="myAddition" type="myAdditionType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:complexType name="myAdditionType">
        <xs:sequence>
            <xs:element name="myAdditionA" type="myAdditionAType" minOccurs="0"/>
            <xs:element name="myAdditionB" type="myAdditionBType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="myAtt" type="stringType" use="required" fixed="myValue"/>
    </xs:complexType>
    <xs:simpleType name="myAdditionAType">
        <xs:restriction base="AType">
            <xs:maxLength value="10"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="myAdditionBType">
        <xs:restriction base="AType"/>
    </xs:simpleType>
</xs:schema>

任何人都可以帮我找到正确的方向吗?

1 个答案:

答案 0 :(得分:0)

与此同时,我发现了一个解决方案,下一个XSLT完美运行。有没有人对它有任何改进?

<强> XSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs xdt err fn" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xdt="http://www.w3.org/2005/xpath-datatypes" xmlns:err="http://www.w3.org/2005/xqt-errors">
    <xsl:output method="xml" indent="yes"/>

    <!-- copy all nodes and attributes-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- For each complexType do this -->
    <xsl:template match="/xs:schema/xs:complexType/xs:sequence">
        <xsl:element name="xs:sequence">
            <!-- Loop through each element within the sequence -->
            <xsl:for-each select="xs:element">
                <xsl:choose>
                    <!-- When current element is the last one and all elements are only simpleTypes, add the myAddition after it -->
                    <xsl:when test="current()/@name = ../xs:element[last()]/@name and not(../xs:element[@type=/xs:schema/xs:complexType[xs:attribute/@name='myAtt']/@name])">
                        <xsl:copy>
                            <xsl:apply-templates select="@*|node()"/>
                        </xsl:copy>
                        <xsl:element name="xs:element">
                            <xsl:attribute name="maxOccurs">unbounded</xsl:attribute>
                            <xsl:attribute name="minOccurs">0</xsl:attribute>
                            <xsl:attribute name="name">myAddition</xsl:attribute>
                            <xsl:attribute name="type">myAdditionType</xsl:attribute>
                        </xsl:element>
                    </xsl:when>
                    <!-- When current element is complexType and is the first one with attribute myAtt in it, add myAddition in front of it -->
                    <xsl:when test="current()/@type = /xs:schema/xs:complexType/@name and current()/@name = ../xs:element[@type=/xs:schema/xs:complexType[xs:attribute/@name='myAtt']/@name][1]/@name">
                        <xsl:element name="xs:element">
                            <xsl:attribute name="maxOccurs">unbounded</xsl:attribute>
                            <xsl:attribute name="minOccurs">0</xsl:attribute>
                            <xsl:attribute name="name">myAddition</xsl:attribute>
                            <xsl:attribute name="type">myAdditionType</xsl:attribute>
                        </xsl:element>
                        <xsl:copy>
                            <xsl:apply-templates select="@*|node()"/>
                        </xsl:copy>
                    </xsl:when>
                    <!-- All other cases just copy the current element -->
                    <xsl:otherwise>
                        <xsl:copy>
                            <xsl:apply-templates select="@*|node()"/>
                        </xsl:copy>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

    <!-- After last complexType in file add definition of myAddition -->
    <xsl:template match="/xs:schema/xs:complexType[last()]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:element name="xs:complexType">
            <xsl:attribute name="name">myAdditionType</xsl:attribute>
            <xsl:element name="xs:sequence">
                <xsl:element name="xs:element">
                    <xsl:attribute name="minOccurs">0</xsl:attribute>
                    <xsl:attribute name="name">myAdditionA</xsl:attribute>
                    <xsl:attribute name="type">myAdditionAType</xsl:attribute>
                </xsl:element>
                <xsl:element name="xs:element">
                    <xsl:attribute name="minOccurs">0</xsl:attribute>
                    <xsl:attribute name="name">myAdditionBValue</xsl:attribute>
                    <xsl:attribute name="type">myAdditionBType</xsl:attribute>
                </xsl:element>
            </xsl:element>
            <xsl:element name="xs:attribute">
                <xsl:attribute name="fixed">myValue</xsl:attribute>
                <xsl:attribute name="name">myAtt</xsl:attribute>
                <xsl:attribute name="type">stringType</xsl:attribute>
                <xsl:attribute name="use">required</xsl:attribute>
            </xsl:element>
        </xsl:element>
        <xsl:element name="xs:simpleType">
            <xsl:attribute name="name">myAdditionAType</xsl:attribute>
            <xsl:element name="xs:restriction">
                <xsl:attribute name="base">AType</xsl:attribute>
                <xsl:element name="xs:maxLength">
                    <xsl:attribute name="value">10</xsl:attribute>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:element name="xs:simpleType">
            <xsl:attribute name="name">myAdditionBType</xsl:attribute>
            <xsl:element name="xs:restriction">
                <xsl:attribute name="base">AType</xsl:attribute>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>