XSLT-разделение на основе дочерних данных - PullRequest
0 голосов
/ 09 марта 2011

У меня есть:

<?xml version="1.0" encoding="utf-8"?>
<parent>
 <parentspecialinfo>blond</parentspecialinfo>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
  <child>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>999</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
</parent>

Мне нужно скопировать весь набор дочерних записей в новый родительский элемент, сохраняя всю информацию о родительских узлах для каждого уникального набора specialvalue, где grandchildtype является особенным.Так что для этого примера у нас есть только 2, 123 и 999. Но может быть много наборов уникальных значений.У меня возникли проблемы с перемещением вверх по цепочке, чтобы сохранить все элементы.Я экспериментировал с использованием элемента xsl: key, но не продвинулся далеко.Это хорошее решение для этой проблемы?

Таким образом, это будет результатом:

<?xml version="1.0" encoding="utf-8"?>
<parent>
  <parentspecialinfo>blond</parentspecialinfo>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
  <child>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>123</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
</parent>
<parent>
  <parentspecialinfo>blond</parentspecialinfo>
  <child>
    <grandchild>
      <grandchildtype>red</grandchildtype>
      <specialvalue>345</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>blue</grandchildtype>
      <specialvalue>678</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <grandchild>
      <grandchildtype>special</grandchildtype>
      <specialvalue>999</specialvalue>
      <otherstuff>123</otherstuff>
      <otherstuff2>abc</otherstuff2>
      <otherstuff3>zxc</otherstuff3>
    </grandchild>
    <otherchildthings>tiger</otherchildthings>
  </child>
</parent>

Как меня попросили прояснить, вот мой обход кода psuedo из моего решения LINQ.Надеюсь, это поможет: 1) Создать набор узлов оболочки, скопировав <parent>.2) Удалите все элементы <child> из узла оболочки.3) Запрос оригинального документа для всех <child> узлов.4) Для каждого узла <child> найдите значение <specialvalue>, где значение <grandchildtype> является "специальным". 5) Проверьте, видели ли мы уже <specialvalue>, если нет, то добавьте <child> в коллекцию целиком.Если мы уже видели его, найдите его в коллекции и добавьте в коллекцию в этом месте.6) Для каждого значения коллекции добавьте узлы <child> к новому узлу оболочки, созданному на шаге 1. 7) Добавьте все узлы, созданные выше, в один и тот же документ.

Спасибо.

1 Ответ

0 голосов
/ 09 марта 2011

Обновление : с новым источником ввода эта таблица стилей (перезаписывает правило идентификации):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kChildBySpecialvalue"
             match="child"
             use="concat(
                     generate-id(..),'+',
                     grandchild[grandchildtype='special']/specialvalue
                  )"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="parent">
        <xsl:variable name="vCurrent" select="."/>
        <xsl:for-each select="child[
                                 count(.|key('kChildBySpecialvalue',
                                             concat(
                                                generate-id($vCurrent),'+',
                                                grandchild[
                                                   grandchildtype = 'special'
                                                ]/specialvalue
                                             )
                                         )[1]
                                 ) = 1
                              ]">
            <xsl:variable name="vGroup"
                          select="key('kChildBySpecialvalue',
                                      concat(
                                         generate-id($vCurrent),'+',
                                         grandchild[
                                            grandchildtype = 'special'
                                         ]/specialvalue
                                      )
                                  )"/>
            <xsl:for-each select="$vCurrent">
                <xsl:copy>
                    <xsl:apply-templates
                         select="node()[not(self::child)]|$vGroup|@*"/>
                </xsl:copy>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Выход:

<parent>
    <parentspecialinfo>blond</parentspecialinfo>
    <child>
        <grandchild>
            <grandchildtype>special</grandchildtype>
            <specialvalue>123</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>red</grandchildtype>
            <specialvalue>345</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>blue</grandchildtype>
            <specialvalue>678</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <otherchildthings>tiger</otherchildthings>
    </child>
    <child>
        <grandchild>
            <grandchildtype>special</grandchildtype>
            <specialvalue>123</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <otherchildthings>tiger</otherchildthings>
    </child>
</parent>
<parent>
    <parentspecialinfo>blond</parentspecialinfo>
    <child>
        <grandchild>
            <grandchildtype>red</grandchildtype>
            <specialvalue>345</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>blue</grandchildtype>
            <specialvalue>678</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <grandchild>
            <grandchildtype>special</grandchildtype>
            <specialvalue>999</specialvalue>
            <otherstuff>123</otherstuff>
            <otherstuff2>abc</otherstuff2>
            <otherstuff3>zxc</otherstuff3>
        </grandchild>
        <otherchildthings>tiger</otherchildthings>
    </child>
</parent>

Примечание : Gruping parent s child потомков на specialvalue, когда grandchildtype равно 'special'; копирование себя, других детей и группы для каждой группы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...