2013-11-23 2 views
0

У меня есть одна конкретная проблема. У меня есть XML, который мне понадобится преобразовать, чтобы один узел был скопирован.Скопируйте узел XML с добавленными изменениями дочерних узлов

Входной XML является:

<root> 
    <book> 
     <name> 
     ... some data 
     </name> 
     <info> 
     ... some data 
     </info> 
     <trees> 
      <tag1></tag1> 
      <tag2></tag2> 
      <tag3></tag3> 
      .... other tags 
      <tag n+1></tag n+1> 
     </trees> 
     . 
     . 
     . 
     other nodes 
     . 
     . 
     . 
     . 
     </book> 
     <book> 
     . 
     . 
     . 
     </book> 
</root> 

Теперь я должен был бы скопировать узел «деревья» 3 раза и написать это с небольшими изменениями в суб узлов. Вывод XML должен был бы быть похожим:

<root> 
    <book> 
     <name> 
     ... some data 
     </name> 
     <info> 
     ... some data 
     </info> 

     <trees> 
      <tag1></tag1> 
      <tag2></tag2> 
      <tag3></tag3> 
      .... other tags 
      <tag n+1></tag n+1> 
     </trees> 
     <treesA> 
      <tag1A></tag1A> 
      <tag2A></tag2A> 
      <tag3A></tag3A> 
      .... other tags 
      <tag n+1></tag n+1> 
     </treesA> 
     <treesA> 
      <tag1B></tag1B> 
      <tag2B></tag2B> 
      <tag3B></tag3B> 
      .... other tags 
      <tag n+1></tag n+1> 
     </treesB> 
     <treesC> 
      <tag1C></tag1C> 
      <tag2C></tag2C> 
      <tag3C></tag3C> 


    .... other tags 
     <tag n+1></tag n+1> 
    </treesC> 
    . 
    . 
    . 
    other nodes 
    . 
    . 
    . 
    . 
</book> 
<book> 
. 
. 
. 
</book> 

Спасибо за вашу помощь по поводу моей проблемы. Eoglasi

ответ

1

Это может быть сделано достаточно хорошо в XSLT 2.0 с помощью параметра туннельного держать суффикс:

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

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

    <xsl:template match="*"> 
    <xsl:param name="suffix" tunnel="yes" select="''" /> 
    <xsl:element name="{name()}{$suffix}" namespace="{namespace-uri()}"> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="trees"> 
    <xsl:next-match /> 
    <xsl:next-match> 
     <xsl:with-param name="suffix" tunnel="yes" select="'A'" /> 
    </xsl:next-match> 
    <xsl:next-match> 
     <xsl:with-param name="suffix" tunnel="yes" select="'B'" /> 
    </xsl:next-match> 
    <xsl:next-match> 
     <xsl:with-param name="suffix" tunnel="yes" select="'C'" /> 
    </xsl:next-match> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Perfect 10 ответов, спасибо , Можете ли вы также сообщить, что это преобразование оставляет все остальное в XML так же, как и раньше? – eoglasi

+0

@eoglasi в значительной степени, единственное, что может измениться, - это если у вас есть пространство имен, объявленное в родительском элементе, но используемое только его потомками (в этом случае объявление будет перемещаться вниз по дереву до точки, где оно используется). Ваш пример XML не содержит пространств имен, поэтому это не должно быть проблемой в вашем случае, но если вы можете попробовать добавить '' непосредственно после открытия '' тег. –

+0

Большое спасибо за ваше объяснение и помощь в этом вопросе. Eoglasi – eoglasi

0

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

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

и

<xsl:template match="trees"> 
    <xsl:call-template name="identity"/> 
    <xsl:apply-templates select="." mode="change"> 
    <xsl:with-param name="suffix" select="'A'"/> 
    </xsl:apply-templates> 
    <xsl:apply-templates select="." mode="change"> 
    <xsl:with-param name="suffix" select="'B'"/> 
    </xsl:apply-templates> 
    <xsl:apply-templates select="." mode="change"> 
    <xsl:with-param name="suffix" select="'C'"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="*" mode="change"> 
    <xsl:param name="suffix"/> 
    <xsl:element name="{name()}{$suffix}" namespace="{namespace-uri()}"> 
    <xsl:apply-templates select="@* | node()" mode="change"> 
     <xsl:with-param name="suffix" select="$suffix"/> 
    </xsl:apply-templates> 
    </xsl:element> 
</xsl:template> 
Смежные вопросы