2010-05-10 3 views
13

Я надеюсь, что вы можете помочь ... Давайте предположим, что я следующий XML:добавить пространство имен + префикс XML с помощью XSL

<data> 
    <token> 
     <sessionId>12345</sessionId>   
     <userId>john</userId> 
     <moreInfo> 
     <bla> ..... 
     </bla> 
     </moreInfo> 
    </token> 
</data> 

И мне это нужно, чтобы стать

<login:data xmlns:login="http://my.ns.uri"> 
     <login:token> 
      <login:sessionId>12345</sessionId>   
      <login:userId>john</userId> 
      <login:moreInfo> 
      <login:bla> ..... 
      </login:bla> 
      </login:moreInfo> 
     </login:token> 
    </login:data> 

Могу ли я сделать это с XSL? Я попытался, но потерпел неудачу ... Любая помощь будет принята с благодарностью!

Спасибо, Jan

+2

На самом деле, что вы производится плохо XML. Вы хотите «xmlns: login =» http: //my.ns.uri ». –

+0

вы правы, вот чего я хочу. xmlns: login = "http: //my.ns.uri" но что будет XSL делать что-то подобное? – Jan

+0

Хороший вопрос (+1). См. Мой ответ для полного и правильного решения. :) –

ответ

12

Использование:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:login="http://my.ns.uri"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

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

<xsl:template match="*"> 
    <xsl:element name="login:{name()}" namespace="http://my.ns.uri"> 
    <xsl:copy-of select="namespace::*"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на прилагаемом документе XML, разыскиваемый, правильный результат получается:

<login:data xmlns:login="http://my.ns.uri"> 
    <login:token> 
     <login:sessionId>12345</login:sessionId> 
     <login:userId>john</login:userId> 
     <login:moreInfo> 
     <login:bla> ..... 
     </login:bla> 
     </login:moreInfo> 
    </login:token> 
</login:data> 
+0

Большое спасибо, это именно то, что я имел в виду и нуждался, вы спасли меня от плохой головной боли :) – Jan

0
<xsl:template match="*"> 
    <xsl:element name="{local-name()}" namespace="http://my.ns.uri"> 
    <xsl:apply-templates /> 
    </xsl:element> 
</xsl:template> 
+0

Хорошо, я это понимаю. Но как я могу изменить префиксы всех элементов? – Jan

+0

Префиксы - это что-то, что довольно гибко в XML. Я имею в виду, что спецификация явно говорит, что они * произвольные *. Таким образом, ваш XSLT-процессор мог бы свободно менять их на все, что ему нравится. Однако каждый (известный мне) движок XSLT повторно использует префиксы, которые вы написали в своем теге '', если нет причин не делать этого (например, XSLT 'exclude-result-prefix'). – Boldewyn

+0

Хорошо, позволь мне поиграть с этим .... Спасибо! – Jan

0

XSLT 2.0 более эффективен и компактен. Он поддерживает непосредственное добавление пространств имен к узлу. Нам не нужно ничего определять в начале таблицы стилей.

Вот спецификации: creating namespace prefix

Использование:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:template match="*"> 
    <xsl:element name="login:{name()}" xmlns:login="http://my.ns.uri"> 
    <xsl:namespace name="login">http://my.ns.uri</xsl:namespace> 
    <xsl:value-of select="node()"/> 
    <xsl:apply-templates select="*"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

Это даст выход:

<login:data xmlns:login="http://my.ns.uri"> 
    <login:token> 
     <login:sessionId>12345</login:sessionId> 
     <login:userId>john</login:userId> 
     <login:moreInfo> 
     <login:bla> ..... 
     </login:bla> 
     </login:moreInfo> 
    </login:token> 
</login:data> 
Смежные вопросы