2013-06-05 2 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> 

Но проблема: У нас есть некоторые XMLs с другим пространством имен т.е. http://sample2.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="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 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, чтобы изменить пространство имен на лету. образец 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> 

Он смотрит на меня, она способна изменить пространство имен, но не в состоянии выбрать элемент после изменения пространства имен. может быть, это относится к старому пространству имен, т.е. 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. Я предполагаю, что вы стали жертвой ошибки копирования/вставки.)

Смежные вопросы