我有大量的XML文件,需要使用XSLT进行转换。问题在于这些文件中的许多文件是由不同的人手写的,它们没有使用一致的名称来引用架构。例如,一个文件可能使用:
xmlns:itemType="http://example.com/ItemType/XSD"
其中另一个可能使用前缀“it”而不是“itemType”:
xmlns:it="http://example.com/ItemType/XSD"
如果那还不够糟糕,那么有几个文件对于同一件事使用两个或三个同义词!


xmlns:it =“http://example.com/ItemType/XSD”
xmlns:itemType =“http://example.com/ItemType/XSD”
xmlns:ItemType =“http://example.com/ItemType/XSD”
...

(显然,进行了很多剪切和粘贴)

现在,由于XSLT文件中的模式匹配似乎可以在 namespace 前缀(与其所涉及的模式相对)上起作用,因此该模式仅匹配变体之一。所以,如果我写这样的话:



然后,它仅匹配我想要的部分案例。

问题1:是否有任何方法可以使XSLT匹配所有变体?

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

我天真地尝试使用“namespace-alias”,但我想我误解了它的作用,因为我根本无法使它做任何事情-匹配所有变体或影响输出XML。

版本=“1.0”
...
xmlns:it =“http://example.com/ItemType/XSD”
xmlns:itemType =“http://example.com/ItemType/XSD”
xmlns:ItemType =“http://example.com/ItemType/XSD”
...



最佳答案

除非您明确声明,否则属性值或文本节点不会强制转换为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>

关于XSLT:如何删除同义词 namespace ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5316102/

10-12 05:43