使用XSL扩展XSD复杂元素类型?

时间:2012-05-14 03:29:21

标签: xml xslt xsd

我有一个XSD文档,我正在尝试使用XSL解析文档,其中complexTypes经常包含其他complexTypes的元素。如果可能的话,我想在容器旁边显示这些复杂类型元素的内容。以下是我正在使用的一个简单示例:

<xs:complexType name="S">
  <xs:sequence>
    <xs:element name="A" type="X"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="X">
  <xs:sequence>
    <xs:element name="F"/>
    <xs:element name="G"/>
    <xs:element name="H"/>
  </xs:sequence>
</xs:complexType>

如何将上述内容显示为:“S包含类型X的A(包含F,G和H)”?

提前感谢您的帮助!

添加了示例:            

  <xsl:for-each select="*">
    <xsl:choose>

      <!-- call template without param -->
      <xsl:when test="name() = 'xs:complexType'">
        <xsl:value-of select="@name"/>
        <xsl:text> contains </xsl:text>

        <xsl:call-template name="top"/>
        <xsl:text>&#xa;</xsl:text>
      </xsl:when>

      <!-- for contained elements with types -->
      <xsl:when test="@type != ''  and  name() = 'xs:element' and $typeToLocate = ''">
        <xsl:value-of select="@name"/>
        <xsl:text> of type </xsl:text>
        <xsl:value-of select="@type"/>
        <xsl:text>(which contains: </xsl:text>

        <!--
          point at which i want processor to return to root, locate the
          indicated complex type, output its contents then continue going
          through schema.
        -->
        <xsl:call-template name="top">
          <xsl:with-param name="typeToLocate" select="@type"/>
        </xsl:call-template>

        <xsl:text>)</xsl:text>
      </xsl:when>

      <!-- when type is located, send it to signal proper output -->
      <xsl:when test="$typeToLocate != ''  and  $typeToLocate = @name">
        <xsl:call-template name="top">
          <xsl:with-param name="typeToLocate" select="$typeToLocate"/>
        </xsl:call-template>
      </xsl:when>

      <!-- for elements contained in indicated type -->
      <xsl:when test="$typeToLocate != ''  and  name() = 'xs:element'">
        <xsl:value-of select="@name"/>
        <xsl:text> </xsl:text>

        <xsl:call-template name="top">
          <xsl:with-param name="typeToLocate" select="$typeToLocate"/>
        </xsl:call-template>
      </xsl:when>

      <!-- for continuing through non-content elements under found type -->
      <xsl:when test="$typeToLocate != ''">
        <xsl:call-template name="top">
          <xsl:with-param name="typeToLocate" select="$typeToLocate"/>
        </xsl:call-template>
      </xsl:when>

      <!-- for ignoring non-content elements during normal processing -->
      <xsl:otherwise>
        <xsl:call-template name="top"/>
      </xsl:otherwise>

    </xsl:choose>
  </xsl:for-each>

</xsl:template>

1 个答案:

答案 0 :(得分:0)

为了广泛回答你的问题,我没有给出具体的样式表,我建议......

(1)创建一个模板以匹配XSD公共级别的复杂类型。所述模板的序列构造函数将直接负责生成像“S”这样的文本。

(2)在所述序列构造函数中,但在所述文本生成之后,在复杂类型节点上调用。这将负责剩余的所需生产,从“包含......”开始。

(3)创建describe-contents模板。这里的序列构造函数将由两部分组成:   (3.1)像“包含”这样的不断生产;   (3.2)调用序列成员的apply-templates。这部分将产生类似“X的X型(其中〜)”

(4)创建一个匹配xs:sequence / xs:element的模板。正如您将从3.2中猜测的那样,序列构造函数将包含3个部分:   (4.1)类似“X的X”(“   (4.2)调用与子复合体类型相关的describe-contents模板);最后   (4.3)“)”的持续生产

如果您的目标仅限于xs:序列和复杂类型,那么应该这样做。尽管如此,这种基于模板的方法,模板大致匹配语法元素,应该可以扩展到xs:choice等。

我假设您确实需要深层复杂类型定义的递归描述。