2009-10-09 6 views
1

У меня есть XML следующим образом:Добавление узла к к другому в XSLT

<configurationData> 
    <path name='b'> 
     <path name='a'> 
     <setting name='s1'> 
     ![CDATA[XXXX]] 
     </setting> 
     <setting name='s2'> 
      XXXX 
     </setting> 
     </path> 
    </path> 
    </configurationData> 

, где configurationData является корневым узлом, и может быть, возможно, вложенные пути с последующим одним или более установочных узлов. Я хочу, чтобы преобразовать узел настройки, чтобы поместить содержимое узла установки в дочерний узел называется значение

<configurationData> 
    <path name='b'> 
     <path name='a'> 
     <setting name='s1'> 
      <value>![CDATA[XXXX]]</value> 
     </setting> 
     <setting name='s2'> 
      <value>XXXX</value> 
     </setting> 
     </path> 
    </path> 
    </configurationData> 

Я должен признать, что я нашел XML дорожный блок умственную и я не могу увидеть, что XSLT использовать:

Это моя попытка:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output encoding ="utf-8" indent="yes" method="xml" version="1.0"/> 

    <xsl:template match='/setting'> 
    <xsl:apply-templates select='setting' /> 
    </xsl:template> 

    <xsl:template match='setting'> 
    <value> 
     <xsl:value-of select='.'/> 
    </value> 
    </xsl:template> 
</xsl:stylesheet> 
+2

+1 для показа вашей работы –

ответ

3

Вы находитесь на 90% пути оттуда. Что вам нужно, это «шаблон идентификации»

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output encoding ="utf-8" indent="yes" method="xml" version="1.0"/> 

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

    <xsl:template match='setting'> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <value> 
       <xsl:value-of select='.'/> 
      </value> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Первый шаблон обрабатывает все узлы, копируя их на выход. Тем не менее, шаблон «настройки», будучи более конкретным, вызывается для узлов «настройки». Этот шаблон копирует сам узел и его атрибуты, а затем переносит значение в тег «значение».

Самая неинтуитивная вещь о XSLT заключается в том, что таблица стилей не является программой, которая управляет процессом. Вместо этого это входной документ XML, который управляет, при этом таблица стилей предоставляет инструкции, которые выбираются и выполняются в соответствии с тем, что находится на входе. Это называется «push». XSL-процессор передает данные в таблицу стилей. XSLT имеет некоторые процедурные возможности, и вы можете написать таблицу стилей в стиле «pull», где стильная таблица пытается управлять процессом, но это сложнее и приводит к жестким для использования таблицам стилей.

Edit: Чтобы включить разделы CDATA заменить:

<xsl:value-of select='.' /> 

с

![CDATA[<xsl:value-of select='.' disable-output-escaping="yes"/>]] 

(хотя и не самое лучшее решение, так как он всегда ставит CDATA в)

+1

Фантастический джим. Только один маленький вопрос - информация CDATA транслитерирована. Мне нужен CDATA, сохраненный как CDATA. –

+0

Просто мысль. Полагаю, я мог бы просто использовать CDATA, не мог бы я? –

+1

@Preet Sangha: Да, объявив 'cdata-section-elements' - см. Мой ответ. Тем не менее, мне было бы все равно, будет ли это CDATA или нет, поскольку на «уровне данных» он эквивалентен. – Tomalak

0

Мое предложение, основанное на Джим Гаррисон ответ:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <xsl:output method="xml" encoding="utf-8" cdata-section-elements="value" /> 

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

    <xsl:template match="setting/text()"> 
    <value> 
     <xsl:value-of select="." /> 
    </value> 
    </xsl:template> 

</xsl:stylesheet> 
+0

большое спасибо. не могли бы вы указать, почему это может быть лучше? –

+0

Это немного менее сложный и более идиоматический. Кроме этого, нет большой разницы. – Tomalak

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