2013-10-24 9 views
0

У меня есть следующий xml, хотел бы заменить пространство имен «http://tester.com» на «http://tester.com/v2», в поле ввода xml. Я отослал решение here от Dimitre, способное придумать один xslt (1.0). Он заменяет пространство имен для всех элементов, однако атрибутов нет. Как мне изменить это, чтобы замена применялась даже для атрибутов?xslt- заменить пространство имен в атрибутах

ввод XML

<a:Root xmlns:a="http://tester.com"> 
    <a:we>er</a:we> 
    <a:ty a:yu="samp">gh</a:ty> 
</a:Root> 

требуемый выход

<a:Root xmlns:a="http://tester.com/v2"> 
    <a:we>er</a:we> 
    <a:ty a:yu="samp">gh</a:ty> 
</a:Root> 

попытался XSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pTarget" select="'http://tester.com'"/> 
<xsl:param name="pRepl" select="'http://tester.com/v2'"/> 

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

<xsl:template match= 
    "*[namespace-uri()='http://tester.com' 
    or 
    namespace::*[.='http://tester.com'] 
    ]"> 

    <xsl:variable name="vNS" select="namespace-uri()"/> 

    <xsl:variable name="vNewNS"> 
    <xsl:choose> 
     <xsl:when test="not($vNS=$pTarget)"> 
     <xsl:value-of select="$vNS"/> 
     </xsl:when> 
     <xsl:otherwise> 

     <xsl:value-of select="$pRepl"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:variable> 

    <xsl:element name="{name()}" namespace="{$vNewNS}"> 
    <xsl:copy-of select= 
    "namespace::* 
     [not(. = $vNS 
      or 
      .='http://tester.com' 
      ) 
     ]"/> 

    <xsl:for-each select= 
    "namespace::* 
     [.='http://tester.com' 
     ]"> 
    <xsl:variable name="vNewNSUri" select= 
    "$pRepl 
    "/> 

    <xsl:variable name="vPrefix" select="name()"/> 

    <xsl:variable name="vPref"> 
     <xsl:if test="$vPrefix"> 
     <xsl:value-of select="concat($vPrefix, ':')"/> 
     </xsl:if> 
    </xsl:variable> 

    <xsl:variable name="vrtfDoc"> 
     <xsl:element name="{$vPref}dummy" 
        namespace="{$vNewNSUri}"/> 
    </xsl:variable> 

    <xsl:copy-of select= 
    "ext:node-set($vrtfDoc)/*/namespace::*[. = $vNewNSUri]"/> 
    </xsl:for-each> 

    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 
+0

Обратите внимание, что решение, которое я ищу, - это просто замена пространства имен. Префикс (или без префикса) на входе должен быть таким же на выходе. – Suresh

ответ

0

Вы хотите что-то вроде этого:

<xsl:template match="a:*"> 
    <xsl:element name="a:{local-name()}" namespace="{$newNamespace}"/> 
    <xsl:apply-templates select="@* | node()"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="@a:*"> 
    <xsl:attribute name="a:{local-name()}" namespace="{$newNamespace}"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

плюс шаблон идентификации для элементов/атрибутов, не входящих в это пространство имен.

+0

Спасибо, Майкл. Здесь всегда вывод будет иметь «а» в качестве префикса. Я хочу, чтобы это не изменилось с ввода. В моем xslt он заменяет пространство имен для элементов (даже он поддерживает префикс пространства имен, то же, что и вход). Однако это не происходит для атрибутов – Suresh

+0

Я не знаю, почему он не работает для вас. Необходимо увидеть полный ввод, вывод и таблицу стилей. –

+0

Micheal. Это заставило ошибку для меня в шаблоне match = "a: @ *">, javax.xml.transform.TransformerException: ожидалось тестирование узла, которое соответствует либо NCName: *, либо QName. – Suresh

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