Гость
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSL: Объединить множеста / 10 сообщений из 10, страница 1 из 1
13.05.2010, 13:16
    #36625492
Duster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Привет. Появилась такая задачка:

Имеется входной XML вида:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<root>
        <container>
                <parent name="p1">
                        <child name="p1-c1" />
                        <child name="p1-c2" />
                </parent>
                <parent name="p2">
                        <child name="p2-c1" />
                        <child name="p2-c2" />
                </parent>
        </container>
        <container>
                <parent name="p1">
                        <child name="p1-c3" />
                        <child name="p1-c4" />
                </parent>
                <parent name="p2">
                        <child name="p2-c3" />
                        <child name="p2-c4" />
                        <child name="p2-c5" />
                </parent>
        </container>
</root>

требуется получить XML:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
<root>
        <parent name="p1">
                <child name="p1-c1" />
                <child name="p1-c2" />
                <child name="p1-c3" />
                <child name="p1-c4" />
        </parent>
        <parent name="p2">
                <child name="p2-c1" />
                <child name="p2-c2" />
                <child name="p2-c3" />
                <child name="p2-c4" />
                <child name="p2-c5" />
        </parent>
</root>

т.е. нужно избавиться от элементов "container", объединив множества узлов одноименных parent'ов.
Имена элементов "parent" произвольные, заранее не известны. Их количество в container может быть произвольным.

Что-то ума не приложу, как это сделать?
...
Рейтинг: 0 / 0
13.05.2010, 13:18
    #36625499
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
//parent/@name='p2'

и тд и тп
...
Рейтинг: 0 / 0
13.05.2010, 13:27
    #36625533
Duster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Konst_One//parent/@name='p2'


В том то и дело, что значения аттрибутов @name для элементов parent произвольные.
...
Рейтинг: 0 / 0
13.05.2010, 13:52
    #36625611
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
через переменную передавайте в шаблон //parent и сравнивайте с предыдущим значением
...
Рейтинг: 0 / 0
13.05.2010, 14:06
    #36625662
Duster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Konst_Oneчерез переменную передавайте в шаблон //parent и сравнивайте с предыдущим значением
Что? Какое предыдущее значение? Я вас совершенно не понял. Может напишите шаблон для тривиального примера из первого сообщения?
...
Рейтинг: 0 / 0
13.05.2010, 14:14
    #36625690
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 <xsl:template match="/"> 
       <xsl:call-template name="pN">
          <xsl:with-param name="N" select="@Name"/>
        </xsl:call-template>  
...


<xsl:template name="pN">
    <xsl:param name="N" select="''" />
  ...
</xsl:template>
...
Рейтинг: 0 / 0
13.05.2010, 14:18
    #36625701
Duster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Вы предлагаете вызывать темпелейт для каждого элемента parent? И каждый вызов темплейта будет выдавать всех-всех детей парента с таким именем?
Тогда темплейт вызовется 2 раза для имени p1 и 2 раза для имени p2. Дубляж не нужен.
Итерироваться по первому (или n-ному) контейнеру тоже нельзя, т.к. там могут быть представлены не все parent'ы
...
Рейтинг: 0 / 0
13.05.2010, 15:42
    #36625968
Duster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Ладно, тогда упростим вопрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
<root>
        <child name="A" />
        <child name="B" />
        <child name="C" />
        <child name="A" />
        <child name="B" />
</root>

Хочу получить множество уникальных значений аттрибутов name, т.е. "А; B; C"
Путь "//child/@name" естественно даст множество "А; B; C; A; B" поэтому не подходит.

PS: нужно, чтобы сделать по этому множеству for-each цикл (в данном примере цикл должен иметь 3 итерации)
...
Рейтинг: 0 / 0
13.05.2010, 16:13
    #36626074
Pasionario
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

  <xsl:key name="k" match="parent" use="@name"/>
  
  <xsl:template match="root">
    <root>
      <xsl:apply-templates select="//parent[generate-id(.) = generate-id(key('k', @name))]"/>
    </root>
  </xsl:template>

  <xsl:template match="parent">
    <parent name="{@name}">
      <xsl:for-each select="key('k', @name)/child">
        <xsl:copy-of select="."/>
      </xsl:for-each>
    </parent>
  </xsl:template> 
  
</xsl:stylesheet>
...
Рейтинг: 0 / 0
13.05.2010, 17:27
    #36626296
Duster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSL: Объединить множеста
Спасибо! Как раз сам набрел на аналогичный пример. Все работает именно так, как нужно.
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSL: Объединить множеста / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]