Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT 1.0的元素上有多个名称空间_Xslt_Namespaces - Fatal编程技术网

使用XSLT 1.0的元素上有多个名称空间

使用XSLT 1.0的元素上有多个名称空间,xslt,namespaces,Xslt,Namespaces,我正在使用Microsoft的XSLT处理器(仅限1.0) XML开头行: <?xml version="1.0" encoding="utf-8"?> <Header xmlns="http:\\OldNameSpace.com"> <Detail> 让下面的XSLT模板拾取我的文档的元素并更改其名称空间 <xsl:template match="*"> <xsl:element name="{name()}" xml

我正在使用Microsoft的XSLT处理器(仅限1.0)

XML开头行:

<?xml version="1.0" encoding="utf-8"?>
<Header xmlns="http:\\OldNameSpace.com">
    <Detail>

让下面的XSLT模板拾取我的文档的
元素并更改其名称空间

<xsl:template match="*">
    <xsl:element name="{name()}" xmlns="http:\\NewNameSpace.com"> 
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

转换为

但是,我现在需要向该名称空间添加第二个名称空间,以便获得以下输出:

<Header xmlns="NewNameSpace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

我试过使用:

<xsl:template match="*">
    <xsl:element name="{name()}" xmlns="NewNameSpace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

但是,我仍然只能获得与原始XSLT模板相同的输出

有人能告诉我为什么会这样吗?

xsl:element(与文本结果元素不同)不会将所有作用域内的名称空间复制到结果中,而只是元素名称9所需的名称空间(从其名称隐式复制或使用名称空间参数指定)

xslt2为这种情况添加了xsl:namespace指令,但在xslt1中,最简单的方法是

在哪里

在祖先的某个地方(例如在xsl:stylesheet上)

这将向输出中添加一个虚假的
xsi:tmp=”“
,然后还会添加一个名称空间声明,
如果您确实需要此名称空间中的属性,例如
xsi:type
,请使用该属性而不是上面提到的tmp,您就完成了。如果您不介意xsi名称空间中额外的、可能无效的属性,那么就完成了。否则,在变量中执行上述操作,然后使用
msxsl:node set
查询变量并删除虚假的额外属性。

如果静态地知道要生成什么名称空间,那么在XSLT 1.0中最简单的方法就是使用xsl:copy of。创建源文档

然后在调用
xsl:element

时执行
此转换:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:old="http:\\OldNameSpace.com"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  exclude-result-prefixes="old xsi">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pNewNamespace" select="'http:\\NewNameSpace.com'"/>

 <xsl:variable name="vXsi" select="document('')/*/namespace::*[name()='xsi']"/>

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

    <xsl:template match="old:*">
        <xsl:element name="{local-name()}" namespace="{$pNewNamespace}">
          <xsl:copy-of select="$vXsi"/>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
<Header xmlns="http:\\OldNameSpace.com">
    <Detail/>
</Header>
<Header xmlns="http:\\NewNameSpace.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Detail/>
</Header>

应用于以下XML文档时

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:old="http:\\OldNameSpace.com"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  exclude-result-prefixes="old xsi">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pNewNamespace" select="'http:\\NewNameSpace.com'"/>

 <xsl:variable name="vXsi" select="document('')/*/namespace::*[name()='xsi']"/>

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

    <xsl:template match="old:*">
        <xsl:element name="{local-name()}" namespace="{$pNewNamespace}">
          <xsl:copy-of select="$vXsi"/>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
<Header xmlns="http:\\OldNameSpace.com">
    <Detail/>
</Header>
<Header xmlns="http:\\NewNameSpace.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Detail/>
</Header>

产生(我猜是)想要的、正确的结果

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:old="http:\\OldNameSpace.com"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  exclude-result-prefixes="old xsi">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pNewNamespace" select="'http:\\NewNameSpace.com'"/>

 <xsl:variable name="vXsi" select="document('')/*/namespace::*[name()='xsi']"/>

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

    <xsl:template match="old:*">
        <xsl:element name="{local-name()}" namespace="{$pNewNamespace}">
          <xsl:copy-of select="$vXsi"/>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
<Header xmlns="http:\\OldNameSpace.com">
    <Detail/>
</Header>
<Header xmlns="http:\\NewNameSpace.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Detail/>
</Header>


您是否介意进一步澄清一下这是如何实现的,因为xslt并不是最有经验的。实现
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“
在xsl:stylesheet声明中似乎对我的输出没有任何影响,try很快会进一步查看该博客,从我所读到的内容来看,这是一个很好的读物,现在,我正在查询文档中第二个名称空间的使用,因为我看不到它允许我们做的三件事有任何用处,在这种情况下,它是没有意义的。当我知道其needed@Mike:不客气。您的问题很容易解决,因为要添加的名称空间是静态已知的。在XSLT1.0中,动态生成名称空间会变得更有趣。大卫·卡莱尔和迈克尔·凯都暗示了这个更具挑战性的案件的解决方案。最近,我使用这种特殊的XSLT 1.0技术给出了一个答案——它还需要使用
xxx:node-set()
扩展函数。@Mike:更具挑战性问题的解决方案:幸运的是,在这种情况下,它是静态的。出于兴趣和学习,应阅读更复杂的解决方案。使用microsofts XSLT processor运行该解决方案,运行良好,在整个应用程序中运行时,在转换过程中引发异常:“相对URI不支持此操作”你知道是什么原因吗?@Mike:很明显,原因在于你没有向我们展示的代码。我建议用一个完整(但尽可能小)的例子问一个新问题,人们可以用它来重新解释问题。