2010-11-18 3 views
3

У меня есть следующий код XMLXSLT разделить на дочерний узел

<para>Lorem ipsum <link>dolor</link> sit amet</para> 

, который я хочу, чтобы преобразовать в

<para>Lorem ipsum </para><link>dolor</link><para> sit amet</para> 

Другими словами: Я хотел бы разделить пункт элемент в позиции где элемент ссылки. Есть ли намеки?

+0

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

ответ

0

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="para"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <xsl:apply-templates select="link" mode="copy"/> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="para/link"/> 
    <xsl:template match="para/link" mode="copy"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <para> 
      <xsl:apply-templates select="following-sibling::node()[1]"/> 
     </para> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<para>Lorem ipsum </para><link>dolor</link><para> sit amet</para> 

Примечание: мелкозернистый ВТП.

Edit: Компактный код:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <xsl:apply-templates select="self::para/link" mode="copy"/> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="para/link"/> 
    <xsl:template match="para/link" mode="copy"> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
    <xsl:template match="node()[preceding-sibling::node()[1] 
            /self::link/parent::para]"> 
     <para> 
      <xsl:call-template name="identity"/> 
     </para> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Следует ли скопировать символ 'para' вместо сгенерированного? Что, если у него есть атрибуты? Bruno

2

Это преобразование:

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

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

<xsl:template match="/*"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="para/text()"> 
    <para><xsl:copy-of select="."/></para> 
</xsl:template> 
</xsl:stylesheet> 

при нанесении на поставленном XML документа:

<para>Lorem ipsum <link>dolor</link> sit amet</para> 

производит разыскиваемого, правильный результат:

<para>Lorem ipsum </para><link>dolor</link><para> sit amet</para> 

Обратите внимание:

  1. Использование правила идентичности скопировать каждый узел как есть.

  2. Первостепенной правила идентичности с шаблонами для обработки только конкретных узлов

  3. предельной простотой и сила, которые следуют от использования 1. и 2. выше.

+0

Привет, Dimitre, спасибо за ваше очень элегантное решение, но у меня есть проблема, что модель контента также позволяет использовать и другие элементы, которые не должны заканчиваться абзацем, как ссылка. Поэтому мне пришлось использовать предложение Алехандроса. – Roman

+0

@Roman: Вы можете отредактировать свой вопрос и показать реальную структуру своего XML, тогда я обязательно изменю свой ответ, чтобы соответствовать структуре XML, которую я еще не видел. Никто здесь не clairevoyant. :) –

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