首页 > 解决方案 > 无法为 xsi:type 属性动态创建命名空间节点

问题描述

认为

<myDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:js="urn:myJS1"
       xmlns:ns="urn:myNS1">
   <myElem1  xsi:type="ns:myComplexType"/>
   <myElem2 xsi:type="js:myComplexType"/>
</myDoc>

我想迁移此文档以使用名称空间的版本 2,但需要动态执行此操作,因为我无法预测 xsi:type 的哪些值在实例中。理想情况下,我想要相同的前缀。所以我想要类似的东西

<myDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   <myElem1  xmlns:ns="newNs" xsi:type="ns:myComplexType"/>
   <myElem2 xmlns:js="newNs" xsi:type="js:myComplexType"/>
</myDoc>

我尽最大努力拦截 xsi:type 属性的创建,并尝试为新版本创建命名空间节点。它不工作。

   <?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">

    <xsl:variable name="schemas">
        <thing targetNamespace="newNs"/>
    </xsl:variable> 

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>


     <xsl:template match="@xsi:type">
      <xsl:copy copy-namespaces="no">       
         <xsl:namespace name="{substring-before(.,':')}" select="$schemas/thing/@targetNamespace"/>
         <xsl:next-match/>       
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

但这不会导致实例显示新的命名空间节点。

虽然我的示例是 XSLT 2.0,但 XSLT 3.0 解决方案很好。

标签: xsltxml-namespacesxsitype

解决方案


match="@xsi:type"模板中,上下文节点就是@xsi:type属性本身,所以选择@xsi:type是错误的,应该是..

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">

    <xsl:variable name="schemas">
        <thing targetNamespace="newNs"/>
    </xsl:variable> 

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>


     <xsl:template match="@xsi:type">
         <xsl:namespace name="{substring-before(.,':')}" select="$schemas/thing/@targetNamespace"/>
         <xsl:next-match/>       
   </xsl:template>

</xsl:stylesheet>

推荐阅读