2013-03-21 71 views
1

我想創建一個XSLT 2.0樣式表,它將我的XSD轉換爲相同的XSD,但擴展了一些額外的元素。我想添加元素的最後一個簡單類型聲明後和包含屬性myAtt第一複雜類型之前(如果有一個複雜的,最後簡單類型後以其他方式)XSLT:將元素定義添加到XSD中最後一個simpleType之後,並在第一個complexType之前

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> 

誰能幫助我到正確的方向?

回答

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> 
相關問題