Соответствие ключа XSLT пространствам имен
У меня есть 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>
</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
(Тип1 отображается как зависимость типа 2, а тип2 - как зависимость типа 3)
Однако с пространствами имен вывод пуст, имена типов явно не совпадают. Можно ли управлять этим, даже когда пространства имен используются, как в примере? (Я не знаю, как изменить ключ (), чтобы он соответствовал complexType, который использует "targetNamespace" по умолчанию, поэтому не указывает его явно в "name")
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>
</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>
Затем это работает для имен типов с пространством имен и без пространства имен (или их сочетаний) именно так, как мне нужно. При желании также могут быть добавлены две дополнительные возможности, если имя типа может включать пространство имен и ссылаться без пространства имен.