XSLT:如何删除同义名称空间

我有大量的
XML文件,我需要使用XSLT进行转换.问题是许多这些文件是由不同的人手写的,他们不使用一致的名称来引用模式.例如,一个文件可能使用:

的xmlns:ITEMTYPE = “http://example.com/ItemType/XSD”

其他人可能使用前缀“it”而不是“itemType”:

的xmlns:它= “http://example.com/ItemType/XSD”

如果这还不够糟糕,有几个文件使用两个或三个同义词同一个东西!

<?xml version="1.0"?>
<Document
    xmlns:it="http://example.com/ItemType/XSD"
    xmlns:itemType="http://example.com/ItemType/XSD"
    xmlns:ItemType="http://example.com/ItemType/XSD"
    ...

(显然有很多切割和粘贴正在进行中)

现在,因为XSLT文件中的模式匹配似乎在命名空间前缀上工作(而不是与它相关的模式),所以模式只匹配其中一个变体.所以如果我写的东西如下:

    <xsl:template match="SomeNode[@xsi:type='itemType:SomeType']">
        ...
    </xsl:template>

然后它只匹配我想要它的一部分案例.

问题1:有没有办法让XSLT匹配所有变体?

问题2:有没有办法删除重复项,以便所有输出文件使用一致的命名?

我天真地尝试使用“命名空间 – 别名”,但我想我误解了它的作用,因为我根本无法做任何事情 – 要么匹配所有变体,要么影响输出XML.

<?xsl:stylesheet
    version="1.0"
    ...
    xmlns:it="http://example.com/ItemType/XSD"
    xmlns:itemType="http://example.com/ItemType/XSD"
    xmlns:ItemType="http://example.com/ItemType/XSD"
    ...

    <xsl:output method="xml" indent="yes"/>
    <xsl:namespace-alias stylesheet-prefix="it" result-prefix="ItemType"/>
    <xsl:namespace-alias stylesheet-prefix="itemType" result-prefix="ItemType"/>

最佳答案 除非您明确说明,否则属性值或文本节点不会强制转换为QName.虽然这只适用于XSLT / XPath 2.0

在XSLT / XPath 1.0中,您必须“手动”执行此操作:

<xsl:template match="SomeNode">
    <xsl:variable name="vPrefix" select="substring-before(@xsi:type,':')"/>
    <xsl:variable name="vNCName" 
           select="translate(substring-after(@xsi:type,$vPrefix),':','')"/>
    <xsl:if test="namespace::*[
                     name()=$vPrefix
                  ] = 'http://example.com/ItemType/XSD'
                     and
                  $vNCName = 'SomeType'">
        <!-- Content Template -->
    <xsl:if>
</xsl:template>

编辑:所有在一个模式(可读性较差):

<xsl:template match="SomeNode[
                        namespace::*[
                           name()=substring-before(../@xsi:type,':')
                        ] = 'http://example.com/ItemType/XSD'
                           and
                        substring(
                          concat(':',@xsi:type),
                          string-length(@xsi:type) - 7
                        ) = ':SomeType'
                     ]">
    <!-- Content Template -->
</xsl:template>
点赞