Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Удаление ноды из key() / 12 сообщений из 12, страница 1 из 1
08.07.2008, 12:58
    #35417388
alexanderer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Добрый день! Есть хмл
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
<?xml version = '1.0' encoding = 'windows-1251'?>
<root>
   <object_data>
      <AvailableOperations>
         <Operation id="2" orgId="10" roleId="1">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Уведомление1</OperationName>
            <Mandatory>T</Mandatory>
            <DateControl> 2 </DateControl>
            <CommonData/>
         </Operation>
         <Operation id="3" orgId="10" roleId="1">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Уведомление2</OperationName>
            <Mandatory>T</Mandatory>
            <DateControl> 1 </DateControl>
            <CommonData/>
         </Operation>
         <Operation id="4" orgId="10" roleId="1">
            <Group id="2">Регистрация данных2</Group>
            <OperationName>Уведомление3</OperationName>
            <Mandatory>T</Mandatory>
            <DateControl> 1 </DateControl>
            <CommonData/>
         </Operation>
         <Operation id="5" orgId="10" roleId="1">
            <Group id="2">Регистрация данных2</Group>
            <OperationName>Договор3</OperationName>
            <Mandatory>T</Mandatory>
            <DateControl> 1 </DateControl>
            <CommonData/>
         </Operation>
      </AvailableOperations>
   </object_data>
</root>
которую необходимо преобразовать в хмл вида:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
<?xml version = '1.0' encoding = 'Windows-1251'?>
<root>
  <object_data>
    <AvailableOperations>
      <OperationGroup id="1">
        <GroupName>Регистрация данных</GroupName>
        <Operation id="2" orgId="10" roleId="1">
          <OperationName>Уведомление1</OperationName>
          <Mandatory>T</Mandatory>
          <DateControl> 2 </DateControl>
          <CommonData/>
        </Operation>
        <Operation id="3" orgId="10" roleId="1">
          <OperationName>Уведомление2</OperationName>
          <Mandatory>T</Mandatory>
          <DateControl> 1 </DateControl>
          <CommonData/>
        </Operation>
      </OperationGroup>
      <OperationGroup id="2">
        <GroupName>Регистрация данных2</GroupName>
        <Operation id="4" orgId="10" roleId="1">
          <OperationName>Уведомление3</OperationName>
          <Mandatory>T</Mandatory>
          <DateControl> 1 </DateControl>
          <CommonData/>
        </Operation>
        <Operation id="5" orgId="10" roleId="1">
          <OperationName>Договор3</OperationName>
          <Mandatory>T</Mandatory>
          <DateControl> 1 </DateControl>
          <CommonData/>
        </Operation>
      </OperationGroup>
    </AvailableOperations>
  </object_data>
</root>
Т.е ноды Group с одинаковым id становятся главной нодой с названием OperationGroup и она уже содержит все остальные ноды.
Я сделал такое преобразование:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <!--<xsl:import href="file://C:/PieDoc/xml/ww/doc_requisitions.xsl "/>-->
  <xsl:output method = "xml" omit-xml-declaration="no" encoding="Windows-1251"/> 
    <xsl:template match="node()|@*">
      <xsl:copy> 
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>      
    </xsl:template>
    
  <xsl:key name="group" match="Group" use="@id"/>
  <xsl:key match="Operation" name="operationO" use="./*"/> 
  
  <xsl:template match="AvailableOperations">
    <xsl:element name="AvailableOperations">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="Operation">
    <xsl:for-each select="Group[generate-id(.)=generate-id(key('group', @id))]">
        <OperationGroup id="{./@id}">          
          <GroupName><xsl:value-of select="."/></GroupName>
          <xsl:copy-of select="key('operationO', .)"/>
        </OperationGroup>
      </xsl:for-each>
  </xsl:template>
  
</xsl:stylesheet>
В принципе, это преобразование делает то,что надо, однако вместо:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<OperationGroup id="1">
        <GroupName>Регистрация данных</GroupName>
        <Operation id="2" orgId="10" roleId="1">
          <OperationName>Уведомление1</OperationName>
          <Mandatory>T</Mandatory>
          <DateControl> 2 </DateControl>
          <CommonData/>
        </Operation>
        <Operation id="3" orgId="10" roleId="1">
          <OperationName>Уведомление2</OperationName>
          <Mandatory>T</Mandatory>
          <DateControl> 1 </DateControl>
          <CommonData/>
        </Operation>
</OperationGroup>
получается
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<OperationGroup id="1">
            <GroupName>Регистрация данных</GroupName>
            <Operation id="2" orgId="10" roleId="1">
  <Group id="1">Регистрация данных</Group>
              <OperationName>Уведомление1</OperationName>
              <Mandatory>T</Mandatory>
              <DateControl> 2 </DateControl>
              <CommonData/>
         </Operation>
         <Operation id="3" orgId="10" roleId="1">
  <Group id="1">Регистрация данных</Group>
              <OperationName>Уведомление2</OperationName>
              <Mandatory>T</Mandatory>
              <DateControl> 1 </DateControl>
              <CommonData/>
         </Operation>
</OperationGroup>
Как удалить ноду Group из итоговой хмл. Чуствую что должно быть просто, но никак не получается.
Пробовал такую запись <xsl:copy-of select="key('operationO', .)[name()!='Group']">
и <xsl:copy-of select="key('operationO', .[name()!='Group'])">
Результат тот же.
...
Рейтинг: 0 / 0
08.07.2008, 23:00
    #35418956
Volder
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
ключика на самом деле достаточно и одного.
я бы сделал как-то так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<!--<xsl:import href="file://C:/PieDoc/xml/ww/doc_requisitions.xsl "/>-->
	<xsl:output method="xml" omit-xml-declaration="no" encoding="Windows-1251"/>
	<xsl:key match="Operation" name="oper" use="Group/@id"/>

	<xsl:template match="AvailableOperations">
		<xsl:element name="AvailableOperations">
			<xsl:apply-templates select="Operation[generate-id(.)=generate-id(key('oper',Group/@id))]"/>
		</xsl:element>
	</xsl:template>
	
	<xsl:template match="Operation">
		<OperationGroup id="{Group/@id}">
			<GroupName>
				<xsl:value-of select="Group"/>
			</GroupName>
			<xsl:for-each select="key('oper',Group/@id)">
				<Operation id="{@id}" orgId="{@orgId}" roleId="{@roleId}">
					<xsl:copy-of select="*[not(self::Group)]"/>
				</Operation>
			</xsl:for-each>
		</OperationGroup>
	</xsl:template>
</xsl:stylesheet>
...
Рейтинг: 0 / 0
09.07.2008, 12:08
    #35419927
alexanderer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Большое спасибо за ответ.
Только у меня осталось 2 вопоса. Почему записи типа
<xsl:copy-of select="key('operationO', .)[name()!='Group']">и <xsl:copy-of select="key('operationO', .[name()!='Group'])"> (не могу понять как XSLTпроцессор обрабатывает эту инструкцию)
не удаляют из множества нод возвращаемых функцией key() ноды с именем Group.
И 2рой вопрос: существует ли способ многократного преобразования одной и той же ноды т.е. первый раз я получаю
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<OperationGroup id="1">
            <GroupName>Регистрация данных</GroupName>
            <Operation id="2" orgId="10" roleId="1">
  <Group id="1">Регистрация данных</Group>
              <OperationName>Уведомление1</OperationName>
              <Mandatory>T</Mandatory>
              <DateControl> 2 </DateControl>
              <CommonData/>
         </Operation>
         <Operation id="3" orgId="10" roleId="1">
  <Group id="1">Регистрация данных</Group>
              <OperationName>Уведомление2</OperationName>
              <Mandatory>T</Mandatory>
              <DateControl> 1 </DateControl>
              <CommonData/>
         </Operation>
</OperationGroup>
а потом на этот результат наложить что-нибудь типа темплейта котороый скопирует все кроме ноды Group.
...
Рейтинг: 0 / 0
09.07.2008, 12:57
    #35420112
Volder
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
alexandererПочему записи типа
<xsl:copy-of select="key('operationO', .)[name()!='Group']">и <xsl:copy-of select="key('operationO', .[name()!='Group'])"> (не могу понять как XSLTпроцессор обрабатывает эту инструкцию)
не удаляют из множества нод возвращаемых функцией key() ноды с именем Group.а почему они должны это делать?
<xsl:copy-of> делает полную репликацию того узла, который вы указываете в select.
вариант <xsl:copy-of select="key('operationO', .[name()!='Group']) у меня вообще ругнулся на unexpected token "[name()!='Group']"

а <xsl:copy-of select="key('operationO', .)[name()!='Group']"> делает то, что Вы ему и говорите.
сделай копию узла, но только если имя не 'Group'. Т.к. у нас имя Operation - он его полностью и копирует.
Сделайте <xsl:copy-of select="key('operationO', .)[name()!='Operation']"> и поймете разницу.

alexandererИ 2рой вопрос: существует ли способ многократного преобразования одной и той же ноды т.е.
...
а потом на этот результат наложить что-нибудь типа темплейта котороый скопирует все кроме ноды Group.так по-моему нельзя
в трансформациях вы работает с данными, которые в изначальном XML - не промежуточные расчеты.
Конечно, никто Вас не ограничивает сделать трансформацию в два этапа, а дальше у себя, смотря где это нужно, объединить это все в одно действие.
...
Рейтинг: 0 / 0
09.07.2008, 14:05
    #35420368
Volder
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
PS
а чем Вас вариант не устроил, который я привел?

Если нужно динамически аттрибуты по <Operation>, можно вместо:
Код: plaintext
1.
2.
3.
<Operation id="{@id}" orgId="{@orgId}" roleId="{@roleId}">
	<xsl:copy-of select="*[not(self::Group)]"/>
</Operation>
использовать:
Код: plaintext
1.
2.
<Operation>
	<xsl:copy-of select="@*|*[not(self::Group)]"/>
</Operation>
...
Рейтинг: 0 / 0
09.07.2008, 15:37
    #35420756
alexanderer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Нет, меня все устроило в Вашем варианте. Проблема в том, что не понимая до конца механизма функции key() я не могу понять как решить более общюю задачу т.е. из
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
<?xml version = '1.0' encoding = 'windows-1251'?>
<root>
   <object_data>
      <Organizations>
         <Organization id="4" type="1">
            <FullName>Закрытое Акционерное Общество</FullName>
         </Organization>
         <Organization id="5" type="1">
            <FullName>Открытое Акционерное Общество</FullName>
         </Organization>
      </Organizations>
   </object_data>
   <links_object>
      <AssignedRoles>
         <Role id="6" orgId="4">СИСТЕМА  1 </Role>
         <Role id="1" orgId="4">ДИЛЕР  1 </Role>
         <Role id="1" orgId="5">ДИЛЕР  5 </Role>
         <Role id="3" orgId="5">УЧАСТНИК  8 </Role>
      </AssignedRoles>
      <AvailableOperations>
         <Operation id="12" orgId="4" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Устав</OperationName>
            <Mandatory>T2</Mandatory>
            <DateControl> 2 </DateControl>
         </Operation>
         <Operation id="15" orgId="5" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Регистрация</OperationName>
            <Mandatory>T3</Mandatory>
            <DateControl> 3 </DateControl>
         </Operation>
         <Operation id="30" orgId="5" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Контакты</OperationName>
            <Mandatory>T4</Mandatory>
            <DateControl> 4 </DateControl>
            <Shared></Shared>
         </Operation>
         <Operation id="30" orgId="5" roleId="6">
            <Group id="2">Отмена данных</Group>
            <OperationName>Отмена</OperationName>
            <Mandatory>T5</Mandatory>
            <DateControl> 25 </DateControl>
         </Operation>
      </AvailableOperations>
   </links_object>
</root>
получить
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
<?xml version = '1.0' encoding = 'windows-1251'?>
<root>
   <Organizations>
      <Organization id="4" type="1">
         <FullName>Закрытое Акционерное Общество</FullName>
         <AssignedRoles>
            <Role id="6" orgId="4">СИСТЕМА  1 </Role>
            <Role id="1" orgId="4">ДИЛЕР  1 </Role>
         </AssignedRoles>
         <AvailableOperations>
            <OperationGroup id="1" orgId="4">
               <GroupName>Регистрация данных</GroupName>
               <Operation id="12" orgId="4" roleId="6">
                  <Group id="1">Регистрация данных</Group>
                  <OperationName>Устав</OperationName>
                  <Mandatory>T2</Mandatory>
                  <DateControl> 2 </DateControl>
               </Operation>
            </OperationGroup>
         </AvailableOperations>
      </Organization>
      <Organization id="5" type="1">
         <FullName>Открытое Акционерное Общество</FullName>
         <AssignedRoles>
            <Role id="1" orgId="5">ДИЛЕР  5 </Role>
            <Role id="3" orgId="5">УЧАСТНИК  8 </Role>
         </AssignedRoles>
         <AvailableOperations>
            <OperationGroup id="1" orgId="5">
               <GroupName>Регистрация данных</GroupName>
               <Operation id="15" orgId="5" roleId="6">
                  <OperationName>Регистрация</OperationName>
                  <Mandatory>T3</Mandatory>
                  <DateControl> 3 </DateControl>
               </Operation>
               <Operation id="30" orgId="5" roleId="6">
                  <OperationName>Контакты</OperationName>
                  <Mandatory>T4</Mandatory>
                  <DateControl> 4 </DateControl>
                  <Shared/>
               </Operation>
            </OperationGroup>
            <OperationGroup id="2" orgId="5">
               <GroupName>Отмена данны</GroupName>
               <Operation id="30" orgId="5" roleId="6">
                  <OperationName>Отмена</OperationName>
                  <Mandatory>T5</Mandatory>
                  <DateControl> 25 </DateControl>
               </Operation>
            </OperationGroup>
         </AvailableOperations>
      </Organization>
   </Organizations>
</root>
Т.е ноды Role и Operation атрибут orgId которых совпадает с id ноды Organization входят внутрь этой ноды и при этом ноду Operation нужно преобразовать так, как было в самом начале треда.
Придумал только
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="windows-1251"/>

  <xsl:key match="Operation" name="oper" use="@orgId"/>
  <xsl:key match="/root/links_object/AssignedRoles/Role" name="role" use="@orgId"/>
  
  <xsl:template match="/">
    <root>
    <Organizations>
    <xsl:for-each select="/root/object_data/Organizations/Organization">
      <xsl:variable name="currentOrgId" select="@id"/>
      <Organization id="{@id}" type="{@type}">
        <xsl:copy-of select="./*"/>
        <AssignedRoles>
          <xsl:copy-of select="key('role', $currentOrgId)"/>
        </AssignedRoles>
        <AvailableOperations>
         А тут не понятно пока ......
        
         <xsl:for-each select="/root/links_object/AvailableOperations/Operation">
            <xsl:if test="$currentOrgId = @orgId">
              <OperationGroup id="{Group/@id}" orgId="{@orgId}">
                  <GroupName>
                    <xsl:value-of select="Group"/>
                  </GroupName>
                  <xsl:for-each select="key('oper',$currentOrgId)">
                    <Operation id="{@id}" orgId="{@orgId}" roleId="{@roleId}">
                      <xsl:copy-of select="*"/>
                    </Operation>
                  </xsl:for-each>
              </OperationGroup>
            </xsl:if>
          </xsl:for-each>
        </AvailableOperations>
        </Organization>
      </xsl:for-each>
    </Organizations></root>
  </xsl:template>
</xsl:stylesheet>
Все, что я пытаюсь зделать внутри <AvailableOperations> используя key() выдает какие-то множеста элементов, как будто результат key() объединяется между собой. Вобщем пока шоманю...
...
Рейтинг: 0 / 0
09.07.2008, 18:33
    #35421513
alexanderer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Кажется начал немного понимать. Для <xsl:key match="Operation" name="oper" use="@orgId"/> набор нод это
Код: plaintext
1.
2.
3.
4.
5.
        <Operation id="12" orgId="4" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Устав</OperationName>
            <Mandatory>T2</Mandatory>
            <DateControl> 2 </DateControl>
         </Operation>
и
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
         <Operation id="15" orgId="5" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Регистрация</OperationName>
            <Mandatory>T3</Mandatory>
            <DateControl> 3 </DateControl>
         </Operation>
         <Operation id="30" orgId="5" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Контакты</OperationName>
            <Mandatory>T4</Mandatory>
            <DateControl> 4 </DateControl>
            <Shared></Shared>
         </Operation>
         <Operation id="30" orgId="5" roleId="6">
            <Group id="2">Отмена данных</Group>
            <OperationName>Отмена</OperationName>
            <Mandatory>T5</Mandatory>
            <DateControl> 25 </DateControl>
         </Operation>
а для <xsl:key match="Operation" name="group" use="Group/@id"/>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
        <Operation id="12" orgId="4" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Устав</OperationName>
            <Mandatory>T2</Mandatory>
            <DateControl> 2 </DateControl>
         </Operation>
         <Operation id="15" orgId="5" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Регистрация</OperationName>
            <Mandatory>T3</Mandatory>
            <DateControl> 3 </DateControl>
         </Operation>
         <Operation id="30" orgId="5" roleId="6">
            <Group id="1">Регистрация данных</Group>
            <OperationName>Контакты</OperationName>
            <Mandatory>T4</Mandatory>
            <DateControl> 4 </DateControl>
            <Shared></Shared>
         </Operation>
и
Код: plaintext
1.
2.
3.
4.
5.
         <Operation id="30" orgId="5" roleId="6">
            <Group id="2">Отмена данных</Group>
            <OperationName>Отмена</OperationName>
            <Mandatory>T5</Mandatory>
            <DateControl> 25 </DateControl>
         </Operation>
а можно как-то получить набор нод одновременно и для @orgId и для Group/@id?
...
Рейтинг: 0 / 0
10.07.2008, 14:17
    #35423029
alexanderer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Хм... Вобщем как-то получилось. Создал 3 ключа
Код: plaintext
1.
2.
  <xsl:key match="Operation" name="oper" use="@orgId"/>
  <xsl:key match="Operation" name="group" use="Group/@id"/>
  <xsl:key match="Operation" name="test" use="generate-id(.)"/>
и такое преобразование для <AvailableOperations>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  
<AvailableOperations>
   <xsl:for-each select="/root/links_object/AvailableOperations/Operation[generate-id(.)=generate-id(key('oper', $currentOrgId))]">
    <xsl:for-each select="/root/links_object/AvailableOperations/Operation[generate-id(.)=generate-id(key('group', Group/@id))]">
     <xsl:variable name="grp" select="Group/@id"/>            
      <xsl:if test="key('oper', $currentOrgId)/Group/@id = $grp">
       <OperationGroup id="{Group/@id}" orgId="{$currentOrgId}">
        <GroupName>
         <xsl:value-of select="Group"/>
        </GroupName>
        <xsl:for-each select="/root/links_object/AvailableOperations/Operation">
         <xsl:if test="key('test',generate-id())/@orgId = $currentOrgId and key('test',generate-id())/Group/@id=$grp">
          <Operation id="{$grp}" orgId="{$currentOrgId}" roleId="{key('test',generate-id())/@roleId}">
           <xsl:copy-of select="key('test',generate-id())/*[name()!='Group']"/>
          </Operation>
         </xsl:if>
        </xsl:for-each>
       </OperationGroup>
      </xsl:if>
     </xsl:for-each>
    </xsl:for-each>
</AvailableOperations>
Но как это работает, сам до конца не понимаю. Почему правильно отрабатывае блок <xsl:variable name="grp" select="Group/@id"/>
<xsl:if test="key('oper', $currentOrgId)/Group/@id = $grp"> не ясно.
...
Рейтинг: 0 / 0
10.07.2008, 21:37
    #35424156
Volder
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
альтернативый вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<xsl:output method="xml" omit-xml-declaration="no" encoding="Windows-1251"/>
	<xsl:key match="Operation" name="oper1" use="@orgId"/>
	<xsl:key match="Operation" name="oper2" use="concat(@orgId,'~',Group/@id)"/>
	<xsl:key match="Role" name="role" use="@orgId"/>
	<xsl:template match="root">
		<root>
			<Organizations>
				<xsl:apply-templates select="object_data/Organizations/Organization"/>
			</Organizations>
		</root>
	</xsl:template>
	<xsl:template match="Organization">
		<Organizatoin>
			<xsl:variable name="orgid" select="@id"/>
			<xsl:copy-of select="@*|*"/>
			<AssignedRoles>
				<xsl:copy-of select="key('role',@id)"/>
			</AssignedRoles>
			<AvailableOperations>
				<xsl:for-each select="key('oper1',$orgid)[generate-id(.)=generate-id(key('oper2',concat($orgid,'~',Group/@id)))]">
					<OperationGroup id="{Group/@id}">
						<GroupName>
							<xsl:value-of select="Group"/>
						</GroupName>
						<xsl:for-each select="key('oper2',concat($orgid,'~',Group/@id))">
							<Operation>
								<xsl:copy-of select="@*|*[not(self::Group)]"/>
							</Operation>
						</xsl:for-each>
					</OperationGroup>
				</xsl:for-each>
			</AvailableOperations>
		</Organizatoin>
	</xsl:template>
</xsl:stylesheet>
...
Рейтинг: 0 / 0
11.07.2008, 13:52
    #35425515
alexanderer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Все таки результат мне не понятен... Я несколько упростил хмл
Код: 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 = 'windows-1251'?>
<root>
  <Data id="4">Data  1 </Data>
  <Data id="5">Data  2 </Data>
  <Oper orgId="4" roleId="61">
    <Group id="1">Group  1 </Group>
  </Oper>
  <Oper orgId="4" roleId="62">
    <Group id="2">Group  2 </Group>
  </Oper>
  <Oper orgId="5" roleId="63">
    <Group id="1">Group  3 </Group>
  </Oper>
  <Oper orgId="5" roleId="64">
    <Group id="1">Group  4 </Group>
  </Oper>
  <Oper orgId="5" roleId="65">
    <Group id="2">Group  5 </Group>
  </Oper>
  <Oper orgId="5" roleId="66">
    <Group id="3">Group  6 </Group>
  </Oper>
</root>
и создал хсл
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="windows-1251"/>
  <xsl:key match="Oper" name="oper" use="@orgId"/>
  <xsl:key match="Oper" name="group" use="Group/@id"/>
  <xsl:template match="/">
    <root>
      <AAA>
        <xsl:for-each select="/root/Data">
          <xsl:variable name="currentId" select="@id"/>
          <xsl:for-each select="/root/Oper[generate-id(.)=generate-id(key('oper', $currentId))]">
            <xsl:for-each select="/root/Oper[generate-id(.)=generate-id(key('group', Group/@id))]">
              <xsl:variable name="grp" select="Group/@id"/>
              <compare>grp=<xsl:value-of select="$grp"/>; 
                       id=<xsl:value-of select="key('oper', $currentId)/Group/@id"/>;
                       if=<xsl:value-of select="key('oper', $currentId)/Group/@id = $grp"/>              
                <xsl:if test="key('oper', $currentId)/Group/@id = $grp">
                  <result>Inside If</result>
                </xsl:if>
              </compare>
            </xsl:for-each>
            </xsl:for-each>
        </xsl:for-each>
      </AAA>
    </root>
  </xsl:template>
</xsl:stylesheet>
результат наложения
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<?xml version = '1.0' encoding = 'windows-1251'?>
<root>
   <AAA>
      <compare>grp= 1 ; id= 1 ; if=true
         <result>Inside If</result>
      </compare>
      <compare>grp= 2 ; id= 1 ; if=true     1 != 2  но результат сравнения true
         <result>Inside If</result>
      </compare>
      <compare>grp= 3 ; id= 1 ; if=false
      </compare>
      <compare>grp= 1 ; id= 1 ; if=true
         <result>Inside If</result>
      </compare>
      <compare>grp= 2 ; id= 1 ; if=true     2 != 1  но результат сравнения true
         <result>Inside If</result>
      </compare>
      <compare>grp= 3 ; id= 1 ; if=true     3 != 1  но результат сравнения true
         <result>Inside If</result>
      </compare>
   </AAA>
</root>
как такое может быть? Такое впечатление что в <xsl:if> key('oper', $currentId)/Group/@id пробегает по всем Group/@id каждой ноды из набора возвращаемых нод, однако <xsl:value-of select="key('oper', $currentId)/Group/@id"/> возвращает только первое id. Что это? Особенность <xsl:if>?
...
Рейтинг: 0 / 0
12.07.2008, 19:17
    #35426878
Volder
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
alexandererкак такое может быть? Такое впечатление что в <xsl:if> key('oper', $currentId)/Group/@id пробегает по всем Group/@id каждой ноды из набора возвращаемых нод, однако <xsl:value-of select="key('oper', $currentId)/Group/@id"/> возвращает только первое id. Что это? Особенность <xsl:if>?это скорее особенность <xsl:value-of> причем только для XSLT 1.0:

INPUT XML:
Код: plaintext
1.
2.
3.
4.
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
   <val> 1 </val>
   <val> 2 </val>
</root>

XSLT 1.0:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/root">
      <root>
         <val1>
            <xsl:value-of select="val"/>
         </val1>
         <val2>
            <xsl:value-of select="val=2"/>
         </val2>
      </root>
   </xsl:template>
</xsl:stylesheet>

RESULT for XSLT 1.0:
Код: plaintext
1.
2.
3.
4.
  <?xml version="1.0" encoding="UTF-8" ?> 
- <root>
  <val1> 1 </val1> 
  <val2>true</val2> 
  </root>

для того же XML применим XSLT 2.0:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/root">
      <root>
         <val1>
            <xsl:value-of select="val"/>
         </val1>
         <val2>
            <xsl:value-of select="val=2"/>
         </val2>
      </root>
   </xsl:template>
</xsl:stylesheet>

RESULT for XSLT 2.0:
Код: plaintext
1.
2.
3.
4.
  <?xml version="1.0" encoding="UTF-8" ?> 
- <root>
  <val1> 1   2 </val1> 
  <val2>true</val2> 
  </root>
...
Рейтинг: 0 / 0
12.07.2008, 23:09
    #35427005
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление ноды из key()
Код: plaintext
1.
2.
3.
<xsl:value-of
  select = Expression
  disable-output-escaping = "yes" | "no" 
</xsl:value-of>

Attributes
select
Required. The Expressions to be evaluated against the current context. The results are converted to a string, as by a call to the string() function. A node-set is converted to a string by inserting the string value of the first node in the set.

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Удаление ноды из key() / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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