【问题标题】:XSLT key matching with namespaces与命名空间匹配的 XSLT 键
【发布时间】:2016-08-26 16:55:09
【问题描述】:

我有一个使用命名空间的 XSD 文档,简化为:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xns="urn:MyNs" targetNamespace="urn:MyNs">
  <xs:complexType name="Type1">
    <xs:sequence>
      <xs:element name="xxx" type="xs:short" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Type2">
    <xs:sequence>
      <xs:element name="yyy" type="xs:short" />
      <xs:element name="value" type="xns:Type1" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Type3">
    <xs:sequence>
      <xs:element name="yyy" type="xs:short" />
      <xs:element name="value" type="xns:Type2" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

我需要处理该文件中的类型依赖关系,为此我有以下 XSL(再次简化为最小示例):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text" encoding="utf-8" indent="yes"/>

    <xsl:param name="debug" select="no"/>

    <xsl:strip-space elements="*"/>

    <xsl:key name="type" match="xs:complexType" use="@name"/>

    <xsl:template match="*" mode="print-dependency">
        <xsl:value-of select="@name"/>
        <xsl:text>&#x0a;</xsl:text>
    </xsl:template>

    <xsl:template match="*" mode="process-type">
        <xsl:apply-templates mode="print-dependency"
                select="key('type', (
                    xs:attribute | xs:complexContent/xs:extension//xs:attribute |
                    xs:sequence/xs:element | xs:complexContent/xs:extension/xs:sequence/xs:element
                )/@type)"/>
    </xsl:template>

    <xsl:template match="/xs:schema">
        <xsl:apply-templates select="xs:complexType" mode="process-type">
            <xsl:with-param name="debug" select="$debug"/>
        </xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>

如果我在输入 XSD 文件中没有命名空间(即,如果我删除“xns”),则输出如预期:

Type1
Type2

(Type1显示为Type 2的依赖,Type2显示为Type3的依赖)

但是,对于命名空间,输出为空,类型名称显然不匹配。即使像示例中那样使用命名空间,是否也可以管理它? (我不知道如何更改 key() 以匹配默认使用“targetNamespace”的 complexType,因此没有在“name”中明确指定它)

【问题讨论】:

  • 从 XML/XSLT 的角度来看,type="xns:Type1" 中的 xns: 前缀不是命名空间,而是一个无意义的字符串。如果您想使用属性的值作为匹配name="Type1" 的键,则需要使用substring-after(@type, ':')
  • 根据你的评论解决了,看答案。感谢您的提示:)

标签: xslt xsd namespaces xslkey


【解决方案1】:

好的,所以要根据@michael 的评论回答我自己的问题,我通过使用此 XSLT 使其工作 - 删除 key() 并改为使用显式匹配,用于非剥离和剥离字符串:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text" encoding="utf-8" indent="yes"/>

    <xsl:param name="debug" select="no"/>

    <xsl:strip-space elements="*"/>

    <xsl:key name="type" match="xs:complexType" use="@name"/>

    <xsl:template match="*" mode="print-dependency">
        <xsl:value-of select="@name"/>
        <xsl:text>&#x0a;</xsl:text>
    </xsl:template>

    <xsl:template match="*" mode="process-dependency">
        <xsl:variable name="type" select="@type"/>
        <xsl:apply-templates mode="print-dependency"
                select="//xs:complexType[@name=$type]"/>
        <xsl:apply-templates mode="print-dependency"
                select="//xs:complexType[@name=substring-after($type, ':')]"/>
    </xsl:template>

    <xsl:template match="*" mode="process-type">
        <xsl:apply-templates mode="process-dependency"
                select="(
                    xs:attribute | xs:complexContent/xs:extension//xs:attribute |
                    xs:sequence/xs:element | xs:complexContent/xs:extension/xs:sequence/xs:element
                )"/>
    </xsl:template>

    <xsl:template match="/xs:schema">
        <xsl:apply-templates select="xs:complexType" mode="process-type">
            <xsl:with-param name="debug" select="$debug"/>
        </xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>

这对于命名空间和非命名空间类型名称(或它们的混合)都适用,完全符合我的需要。如果类型名称可以包含命名空间并且在没有命名空间的情况下被引用,则还可以选择添加两个额外的可能性。

【讨论】:

    猜你喜欢
    • 2011-11-08
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多