2013-04-23 1 views
0

Я новичок в xslt. Я пытаюсь преобразовать XML из одной схемы в другую схему. Я хочу «избавиться» от старого пространства имен после преобразования. Как я могу удалить старую схему после преобразования, если мне это нужно для самого преобразования. По сути, я хочу, чтобы http://positionskillmanagementservice.webservices.com ушел и полностью был заменен http://newschema (после того, как я переименовал узлы). Я в состоянии сделать большую часть того, что я хочу с помощью метода Dimitre Novatchev в от: change the namespace of an element with xsltизбавиться от старого пространства имен с помощью xslt

Это XML:

<ns:positionSkillResponse xmlns:ns="http://positionskillmanagementservice.webservices.com"> 
<ns:return>1</ns:return> 
<ns:return>9</ns:return> 
</ns:positionSkillResponse> 

Это XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns="http://positionskillmanagementservice.webservices.com" 
    version="1.0"> 

    <xsl:output method="xml" /> 

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

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

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

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

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

Я проверяю работу с this tool.

ответ

1

Ваша попытка слишком специфична. Попробуйте более общий характер:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns_old="http://positionskillmanagementservice.webservices.com" 
>  
    <xsl:output method="xml" /> 

    <!-- matches any node not handled elsewhere --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template>  

    <!-- matches elements in the old namespace, re-creates them in the new --> 
    <xsl:template match="ns_old:*"> 
     <xsl:element name="ns:{local-name()}" namespace="http://newschema"> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:element> 
    </xsl:template> 

    <!-- if you don't have namespaced attributes you won't need this template --> 
    <xsl:template match="@ns_old:*"> 
     <xsl:attribute name="ns:{local-name()}" namespace="http://newschema"> 
      <xsl:value-of select="."/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

, который обеспечивает:

<ns:positionSkillResponse xmlns:ns="http://newschema"> 
    <ns:return>1</ns:return> 
    <ns:return>9</ns:return> 
</ns:positionSkillResponse> 

Примечания

  • Вам не нужно объявлять xmlns:ns="http://newschema" в XSLT, потому что вы на самом деле не имеют узлов из это пространство имен в вашем исходном документе.
  • Это также означает, что вы можете объявить старое пространство имен как xmlns:ns="http://positionskillmanagementservice.webservices.com" и использовать его как <xsl:template match="ns:*">. Это все равно для XSL-процессора, но, вероятно, он менее запутан для человеческого читателя, если используется другой префикс, такой как ns_old.
  • Вы можете выбрать выходной префикс произвольно (<xsl:element name="ns:{local-name()}" ...). Это не имеет ничего общего с объявленными пространствами имен в XSLT. не используя никакого префикса вообще приведет к документу с пространством имен по умолчанию:

    <positionSkillResponse xmlns="http://newschema"> 
        <return>1</return> 
        <return>9</return> 
    </positionSkillResponse> 
    
2

Томалак показал вам лучший способ, чтобы написать ваше преобразование, но на самом деле не ответил на ваш вопрос сразу же. Когда вы используете литеральные элементы результата в ваших таблицах стилей, например <a>...</a>, они копируются в вывод вместе со всеми пространствами имен, которые находятся в области видимости для этого элемента в таблице стилей, за некоторыми исключениями. Одним из исключений является то, что пространства имен опущены, если они указаны в элементе exclude-result-prefixes, который обычно помещается в элемент xsl: stylesheet вместе с объявлением пространства имен. Поэтому, если вы не рефакторируете таблицу стилей, как предлагает Tomalak, вы могли бы отказаться от пространства имен, добавив в элемент xsl: stylesheet exclude-result-prefixes = "ns".

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