2010-10-22 8 views
0

мне нужно изменить все дочерние элементы в XML-документа под первым Родитель (и отбросить все остальные родительскую данные)XSLT - переставить все дочерние элементы в рамках первого родительского элемента

В приведенном ниже примере, мне нужно все 4 дочерние элементы под Parent [ParentField = 1] и выбросьте Parent [ParentField = X]

<xml> 
    <Parent> 
     <ParentField>1</ParentField> 
     <Children> 
      <Child> 
       <id>1</id> 
      </Child> 
      <Child> 
       <id>2</id> 
      </Child> 
     </Children> 
    </Parent> 
    <Parent> 
     <ParentField>X</ParentField> 
     <Children> 
      <Child> 
       <id>3</id> 
      </Child> 
      <Child> 
       <id>4</id> 
      </Child> 
     </Children> 
    </Parent> 
</xml> 

Результирующее в XML следующим образом:

<xml> 
    <Parent> 
     <ParentField>1</ParentField> 
     <Children> 
      <Child> 
       <id>1</id> 
      </Child> 
      <Child> 
       <id>2</id> 
      </Child> 
      <Child> 
       <id>3</id> 
      </Child> 
      <Child> 
       <id>4</id> 
      </Child> 
     </Children> 
    </Parent> 
</xml> 

ответ

2

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pParentField" select="1"/> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="Parent"> 
     <xsl:if test="ParentField = $pParentField"> 
      <xsl:call-template name="identity"/> 
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="Children"> 
     <xsl:copy> 
      <xsl:apply-templates select="/xml/Parent/Children/Child"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<xml> 
    <Parent> 
     <ParentField>1</ParentField> 
     <Children> 
      <Child> 
       <id>1</id> 
      </Child> 
      <Child> 
       <id>2</id> 
      </Child> 
      <Child> 
       <id>3</id> 
      </Child> 
      <Child> 
       <id>4</id> 
      </Child> 
     </Children> 
    </Parent> 
</xml> 
+0

Спасибо Alejandro - хотя в конце концов я нашел плохое решение, я буду использовать ваше! – StuartLC

+0

@nonnb: Вы хорошо. Кроме того, проверьте мой комментарий к вашему решению. Теперь это больше не уменьшено ... – 2010-10-22 20:25:08

0

FWIW следующее также, кажется, работает, но выглядит действительно «orrible. Решение Алехандро более элегантно.

<xsl:template match="/"> 
    <xsl:apply-templates select="xml" /> 
</xsl:template> 
<xsl:template match="xml"> 
    <Parent> 
     <xsl:for-each select="Parent[1]"> 
      <ParentField><xsl select...><ParentField> 
     </xsl:for-each> 
     <Children> 
     <xsl:for-each select="//Child"> 
      <Child> 
       <...> 
      </Child> 
     </xsl:for-each> 
    </Parent> 
</xsl:template> 

Edit: Алехандро комментарий рядный для целей форматирования :)

Push-стиль не является плохим решением, когда вы знаете, схемы. Но я думаю, что было бы лучше:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pParentField" select="1"/> 
    <xsl:template match="/"> 
     <xml> 
     <Parent> 
      <xsl:copy-of select="Parent[ParentField=$pParentField]"/> 
      <Children> 
      <xsl:copy-of select="/xml/Parent/Children/Child"/> 
      </Children> 
     </Parent> 
     </xml> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Стиль Push - неплохое решение, когда вы знаете свою схему. Но я думаю, что было бы лучше: '' – 2010-10-22 15:38:18

+1

Полная таблица стилей в комментарии !? Это для тех, кто жалуется на вербальность XSLT ... – 2010-10-22 15:42:43

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