2013-06-05 12 views
1

样品XSLT采摘:在动态XSLT转换更改名称空间不通过XSLT进一步转变

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xslnsv="http://sample2.1"> 
<xsl:output method="xml" indent="yes"/> 

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

<xsl:template match="//xslnsv:Activity"> 
    <xsl:copy> 
    <xsl:copy-of select="@*" /> 
    <xsl:if test="not(@IsForCompensation) 
     and (./xslnsv:IsForCompensationSpecified)"> 
     <xsl:attribute name="IsForCompensation"> 
     <xsl:value-of 
      select="./xslnsv:IsForCompensationSpecified" /> 
     </xsl:attribute> 
    </xsl:if> 
    <xsl:apply-templates 
     select="@*|node()[local-name() 
     != 'IsForCompensationSpecified']" /> 
    </xsl:copy> 
</xsl:template>  
</xsl:stylesheet> 

在这里,我们有一个命名空间的xmlns:xslnsv =“HTTP://sample2.2” 它工作的时候,我们具有相同的命名空间一个xml

<?xml version="1.0" encoding="utf-8"?> 
<Package xmlns="http://sample2.2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" > 
    <ElementAtLevel1> 
    <ElementAtLevel2 Id="cf9d2" Name="Pool 1">  
     <Activities> 
     <Activity Id="ef84125a">   
      <IsForCompensationSpecified 
      >false</IsForCompensationSpecified> 
     </Activity> 
     <Activity Id="39c5b8d8" Name="Task 1"> 
      <IsForCompensationSpecified 
      >true</IsForCompensationSpecified> 
     </Activity> 
     </Activities> 
    </ElementAtLevel2> 
    </ElementAtLevel1> 
    <ExtendedAttributes /> 
</Package> 

以产生输出为:

<?xml version="1.0"?> 
<Package xmlns="http://sample2.2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <ElementAtLevel1> 
    <ElementAtLevel2 Id="cf9d267d-e1ed-4616-adfb-d24d6844f775" 
        Name="Pool 1">  
     <Activities> 
     <Activity Id="ef84125a-0a01-4d76-9b3b-413ffb3c7a74"  
        IsForCompensation="false"/> 
     <Activity Id="39c5b8d8-9a72-40d1-b3e4-8cd973ccdf03" 
        Name="Task 1" 
        IsForCompensation="true"/> 
     </Activities> 
    </ElementAtLevel2> 
    </ElementAtLevel1> 
    <ExtendedAttributes/> 
</Package> 

但问题是: 我们有一些个XML与不同的命名空间具有不同的命名空间

<?xml version="1.0"?> 
<Package xmlns="http://sample2.1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <ElementAtLevel1> 
    <ElementAtLevel2 Id="cf9d267d-e1ed-4616-adfb-d24d6844f775" 
        Name="Pool 1">  
     <Activities> 
     <Activity Id="ef84125a-0a01-4d76-9b3b-413ffb3c7a74" 
        IsForCompensation="false"/> 
     <Activity Id="39c5b8d8-9a72-40d1-b3e4-8cd973ccdf03" 
        Name="Task 1" 
        IsForCompensation="true"/> 
     </Activities> 
    </ElementAtLevel2> 
    </ElementAtLevel1> 
    <ExtendedAttributes/> 
</Package> 

http://sample2.1 示例XML,然后我们没有正确的输出。

<?xml version="1.0" encoding="utf-8"?> 
<Package xmlns="http://sample2.1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" > 
    <ElementAtLevel1> 
    <ElementAtLevel2 Id="cf9d2" Name="Pool 1">  
     <Activities> 
     <Activity Id="ef84125a"> 
      <IsForCompensationSpecified 
      >false</IsForCompensationSpecified> 
     </Activity> 
     <Activity Id="39c5b8d8" Name="Task 1"> 
      <IsForCompensationSpecified 
      >true</IsForCompensationSpecified> 
     </Activity> 
     </Activities> 
    </ElementAtLevel2> 
    </ElementAtLevel1> 
    <ExtendedAttributes /> 
</Package> 

我修改了xslt以实时更改命名空间。有新的变化

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xslnsv="http://sample2.2" > 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:variable name="vUrl" select="'http://sample2.2'"/> 

    <xsl:template match="*[namespace-uri()='http://sample2.1']"> 
    <xsl:element name="{name()}" namespace="{$vUrl}"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 
<xsl:template match="//xslnsv:Activity"> 
    <xsl:copy> 
    <xsl:copy-of select="@*" /> 
    <xsl:if test="not(@IsForCompensation) 
        and (./xslnsv:IsForCompensationSpecified)"> 
     <xsl:attribute name="IsForCompensation"> 
     <xsl:value-of 
      select="./xslnsv:IsForCompensationSpecified" /> 
     </xsl:attribute> 
    </xsl:if> 
    <xsl:apply-templates select="@* 
     |node()[local-name() != 'IsForCompensationSpecified']" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

在我看来 样品XSLT,它是能够改变的命名空间,但是不能改变命名空间后挑元素。可能是它指的是旧的命名空间,即2.1源xml

但仍然没有得到正确的输出;我得到以下输出。

<?xml version="1.0"?> 
<Package xmlns="http://sample2.1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<ElementAtLevel1> 
<ElementAtLevel2 Id="cf9d2" Name="Pool 1">  
<Activities> 
<Activity Id="ef84125a">   
<IsForCompensationSpecified>false</IsForCompensationSpecified> 
</Activity> 
<Activity Id="39c5b8d8" Name="Task 1"> 
<IsForCompensationSpecified>true</IsForCompensationSpecified> 
</Activity> 
</Activities> 
</ElementAtLevel2> 
</ElementAtLevel1> 
<ExtendedAttributes/> 
</Package> 
+1

似乎你被**命名空间**和**命名空间前缀**弄糊涂了。至少在你的第一个例子中,“ns0”是一个名称空间前缀。但在第二个例子中,“ns0”和“ns1”用作uri。所以这让我困惑。 –

+1

谢谢你是对的,我已经更新了 – user2455533

+0

当你说“它不能选择命名空间并且结果转换没有发生”时,你的意思是说处理器不输出任何XML?或者你认为它运行的是标识模板而不是命名空间改变模板?请显示实际输出XML以及相应的输入XML,以便我们可以诊断发生了什么。 – LarsH

回答

1

[修订问题的任择议定书的修订的光。]

如果我理解正确的话,你希望的是,如果命名空间http://sample2.1与localName创建活动的元素在输入中遇到的话( 1)与match="*[namespace-uri()='http://sample2.1']"模板将匹配它并将其移动到命名空间http://sample2.2,然后(2)与match="//xslnsv:Activity"模板将触发。这是一个正确的理解?

如果是这样,这里有两个问题。

首先,命名空间变化模板在名称空间http://sample2.2中生成一个新的元素节点,但是您显示的代码中没有任何内容尝试将任何模板应用于该新元素节点。

第二个问题是XSLT 1.0模板仅匹配输入文档中的元素;他们没有也不能匹配样式表构造的节点。这是XSLT 1.0和XSLT 2.0之间最大的区别之一。 XSLT 1.0的一个通用扩展允许创建的节点通过模板进行匹配;如果你想尝试一下,请查找关于节点集扩展的信息。

一个更简单的解决方案是将样式表分成两部分:一部分将旧命名空间中的元素移至新命名空间,另一部分处理新命名空间中的元素。当我运行你给出的输入样式表时,我得到命名空间http://sample2.2的输出,而不是命名空间http://sample2.1。我假设你是受害者的复制/粘贴错误。)