Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSLT. Преобразование атрибутов в элементы / 23 сообщений из 23, страница 1 из 1
04.12.2012, 11:15
    #38063932
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Добрый день.

Возникла необходимость преобразовать один XML в другой, а точнее все атрибуты элементов первого xml сделать элементами в новом xml и дать им новые имена.
Пример моего первоначального xml:

<?xml version='1.0' encoding='utf-8'?>
<document>
<item name='F'>
<textlist>
<text>Иванов</text>
</textlist>
</item>
<item name='I'>
<textlist>
<text>Семен</text>
</textlist>
</item>
</document>

Что должно получиться в итоге:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationFile xmlns:xsi=" http://www.w3.org/20...chema-instance" xsi:noNamespaceSchemaLocation="Front_Request.xsd">
<ApplicationsList>
<lastname>Иванов</lastname>
<firstname>Семен</firstname>
</ApplicationsList>
</ApplicationFile>

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

<xsl:stylesheet version="1.0" xmlns:xsl=" http://www.w3.org/19...XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*">
<xsl:element name="{local-name(.)}" namespace="{namespace-uri(..)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

В общем вопросы:
1 <xsl:template match="@*"> - эта конструкция выбирает атрибуты на любой "глубине" вложенности?
2 что подставить вместо {local-name(.)}?
3 какое пространство имен указать вместо {namespace-uri(..)}? Обычное xmlns:xsl=" http://www.w3.org/19...XSL/Transform"?

PS: Знаком с XML и XSLT весьма поверхностно. Прошу помощи, а не ссылок.
...
Рейтинг: 0 / 0
04.12.2012, 13:44
    #38064269
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Jackssson,

1 у шаблона нет понятия глубины, эта конструкция отработает всегда, когда ее позовут
2, 3... не поможет, вы нашли некий шаблон для решения конкретной задачи он вам не подходит.

Вы не расписали четких правил мепинга, а начинать надо именно с них, поэтому я буду предполагать.

Вам нужен "тупой" мэппинг, написанный например так:
Код: xml
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.
<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="1.0"
		xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
		xmlns="http://www.w3.org/1999/xhtml"
		xmlns:xsi="http://www.w3.org/20...chema-instance"
		xsi:noNamespaceSchemaLocation="Front_Request.xsd"
>
	<xsl:output method=" чml" indent="yes" />

	<xsl:template match="/">
            <ApplicationFile>
                 <xsl:apply-templates />
            </ApplicationFile>
	</xsl:template>
	<xsl:template match="document">
	    <ApplicationsList>
	         <lastname>
	             <xsl:value-of select="item[@name='F']/textlist/text" />
	         </lastname>
	         <firstname>
	             <xsl:value-of select="item[@name='I']/textlist/text" />
	         </fistname>
	    </ApplicationsList>
	</xsl:template>
</xsl:stylesheet>
...
Рейтинг: 0 / 0
04.12.2012, 13:46
    #38064276
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
очепяточка, так надо
Код: xml
1.
<xsl:output method="xml" indent="yes" />
...
Рейтинг: 0 / 0
04.12.2012, 15:14
    #38064448
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Спасибо большое. Ваше решение у меня работает, но только если не объявлен в самом xml неймспейс.

Код: xml
1.
2.
3.
4.
5.
6.
7.
<?xml version="1.0" encoding="UTF-8"?>
<ApplicationFile>
    <ApplicationsList>
        <lastname>Иванов</lastname>
        <firstname>Семен</firstname>
    </ApplicationsList>
</ApplicationFile>



Если корневой элемент у меня выглядит так, то ничего не работает:

Код: xml
1.
2.
3.
4.
5.
<?xml version='1.0' encoding='utf-8'?>
<document xmlns='http://www.lotus.com/dxl' version='8.5' maintenanceversion='2.3'
 replicaid='44257ABB0031C58A' form='CreditClaim'>
	
</document>



То есть он мне выдает:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?xml version="1.0" encoding="UTF-8"?>
<ApplicationFile>
	
		
			Иванов
		
	
	
		
			Семен
		
	
</ApplicationFile>



Можно ли как то игнорировать пространство имен? Честно говоря не знаю, возможно ли исключить его из выгрузки.
...
Рейтинг: 0 / 0
05.12.2012, 01:02
    #38065386
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Jackssson,

Ммм. Прикольно, сто лет лотус xml не видел, попробуйте для начала заменить в stylesheet соответствующее значение атрибута. Если не получится, думаю, вам гугл поможет.
...
Рейтинг: 0 / 0
05.12.2012, 09:02
    #38065567
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
mage.lanпопробуйте для начала заменить в stylesheet соответствующее значение атрибута.

Честно говоря не совсем понял, о чем речь. Можете пояснить?
...
Рейтинг: 0 / 0
05.12.2012, 09:10
    #38065576
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Jackssson,
Код: xml
1.
2.
3.
4.
<xsl:stylesheet version="1.0"
	...
		xmlns="http://www.lotus.com/dxl"
	...
...
Рейтинг: 0 / 0
07.12.2012, 13:05
    #38069542
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Сделал немного по другому:
есть первый xsl, который тупо копирует xml без namespace`a:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?xml version = "1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="@*|node()[not(self::*)]">
		<xsl:copy/>
	</xsl:template>
	<xsl:template match="*">
		<xsl:element name="{local-name()}">
			<xsl:apply-templates select="node()|@*"/>
		</xsl:element>
	</xsl:template>
</xsl:stylesheet>



и второй, который приводит xml к нужному виду:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="/">
		<ApplicationFile>
			<xsl:apply-templates />
		</ApplicationFile>
	</xsl:template>
	<xsl:template match="document">
		<ApplicationsList>
			<lastname>
				<xsl:value-of select="/document/item[@name='F']/textlist/text"/>
			</lastname>
			<firstname>
				<xsl:value-of select="/document/item[@name='I']/textlist/text"/>
			</firstname>
		</ApplicationsList>
	</xsl:template>
</xsl:stylesheet>



Как их правильно объединить?
...
Рейтинг: 0 / 0
07.12.2012, 13:51
    #38069699
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Jackssson,

а первый нужен вообще? второй без него не работает?
...
Рейтинг: 0 / 0
07.12.2012, 14:33
    #38069821
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
нет, не работает. Там какая то фигня с пространством имен. Решения я не нашел. Если к моему dxl применять только второй xsl, то он не видит вложенных элементов.
...
Рейтинг: 0 / 0
07.12.2012, 15:30
    #38069942
mage.lan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Jacksssonнет, не работает. Там какая то фигня с пространством имен. Решения я не нашел. Если к моему dxl применять только второй xsl, то он не видит вложенных элементов.
ну если первый вариант работает, попробуйте что-нить в этом духе (тяжело гадать, не видя исходный xml):
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="/">
		<ApplicationFile>
			<xsl:apply-templates />
		</ApplicationFile>
	</xsl:template>
	<xsl:template match="*:document">
		<ApplicationsList>
			<lastname>
				<xsl:value-of select="/*:document/*:item[@name='F']/*:textlist/*:text"/>
			</lastname>
			<firstname>
				<xsl:value-of select="/*:document/*:item[@name='I']/*:textlist/*:text"/>
			</firstname>
		</ApplicationsList>
	</xsl:template>
</xsl:stylesheet>
...
Рейтинг: 0 / 0
12.12.2012, 13:29
    #38075685
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Исходный xml очень большой, вот его укороченный вариант:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<?xml version='1.0' encoding='utf-8'?>
<document xmlns='http://www.lotus.com/dxl' version='8.5' maintenanceversion='2.3'
 replicaid='44257ABB0031C58A' form='CreditClaim'>
	<item name='F'>
		<textlist>
			<text>Иванов</text>
		</textlist>
	</item>
	<item name='I'>
		<textlist>
			<text>Семен</text>
		</textlist>
	</item>
</document>


В общем схема трансформации получается такая - dxl(domino xml)=>xsl_1(убирает namespace)=>xsl_2(переименовывает элементы)=>конечный xml.
Появилась идея, сделать некий справочник внешний: имя атрибута в dxl=имя элемента конечного xml, а затем в цикле через переменную подставлять, но работать что то не хочет, пишет что xsl не валидный. Может кто делал такое? Что лучше использовать - import или include? Какова должна быть структура этого отдельного файла-справочника?
...
Рейтинг: 0 / 0
13.12.2012, 13:06
    #38077505
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Разобрался, как использовать внешний xml.
Исходный xml указан выше.
Отдельный xml, который используется как справочник:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
<?xml version='1.0' encoding='utf-8'?>
<root>
	<item dxlName="F">
		lastname
	</item>
	<item dxlName="I">
		firstname
	</item>
</root>


XSL:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	
	<xsl:template match="/">
		<ApplicationFile>
			<xsl:variable name="dictionary" select="document('dictionery.xml')"/>
			<xsl:for-each select="$dictionary/root/item">
				<xsl:variable name="equiName" select="."/>
				<xsl:variable name="dxlName" select="./@dxlName"/>
				<xsl:element name="$equiName" select="ApplicationFile">
					<xsl:value-of select="/document/item[@name='$dxlName']"/>
				</xsl:element>
			</xsl:for-each>
		</ApplicationFile>
	</xsl:template>
</xsl:stylesheet>


При попытке трансформации пишет, что xsl невалидный. Что не так? Может нельзя так использовать переменную?
...
Рейтинг: 0 / 0
13.12.2012, 17:15
    #38078199
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
JacksssonПри попытке трансформации пишет, что xsl невалидный.Прямо так и пишет? Или это Ваш вольный перевод сообщения об ошибке?
...
Рейтинг: 0 / 0
14.12.2012, 11:35
    #38079103
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Ошибка: Unable to apply transformation on current source. Make sure that XSL is valid.
Ну собственно с валидностью xsl я уже разобрался. Чтобы окончательно никого не запутывать объясню все еще раз.
Есть у меня xml(из lotus domino):
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<?xml version='1.0' encoding='utf-8'?>
<document xmlns='http://www.lotus.com/dxl' version='8.5' maintenanceversion='2.3'
 replicaid='44257ABB0031C58A' form='CreditClaim'>
	<item name='F'>
		<textlist>
			<text>Иванов</text>
		</textlist>
	</item>
	<item name='I'>
		<textlist>
			<text>Семен</text>
		</textlist>
	</item>
</document>


Мне надо его привести к виду:
Код: xml
1.
2.
3.
4.
5.
6.
7.
<?xml version="1.0" encoding="utf-8"?>
<ApplicationFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Front_Request.xsd">
	<ApplicationsList>
		<lastname>Иванов</lastname>
		<firstname>Семен</firstname>
	</ApplicationsList>
</ApplicationFile>


То есть что то переименовать, что создать и тд. Пробую все это сделать в цикле и через переменную:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
	<xsl:template match="/">
		<ApplicationFile>
			<!-- <xsl:variable name="dictionary" select="document('dictionary.xml')"/> -->
			<xsl:for-each select="document('dictionary.xml')/root/item">
				<xsl:variable name="equiName">
					<xsl:value-of select="."/>
				</xsl:variable>
				<xsl:variable name="dxlName">
					<xsl:value-of select="./@dxlName"/>
				</xsl:variable>
				<xsl:element name="{$equiName}">
					<xsl:value-of select="/document/item[@name='$dxlName']"/>
				</xsl:element>
			</xsl:for-each>
		</ApplicationFile>
	</xsl:template>
</xsl:stylesheet>


Отдельный xml, в котором описано, что на что будет меняться:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
<?xml version='1.0' encoding='utf-8'?>
<root>
	<item dxlName="F">
		lastname
	</item>
	<item dxlName="I">
		firstname
	</item>
</root>



Использую Oxigen. Сейчас загвоздка в том, что в дебагере, на 13й строке
Код: xml
1.
<xsl:element name="{$equiName}">

он мне пишет, что Invalid element name, хотя в переменной лежит стринг. Не понимаю почему так...
...
Рейтинг: 0 / 0
14.12.2012, 14:28
    #38079460
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Jacksssonхотя в переменной лежит стринг.Какой?
Код: xml
1.
<xsl:value-of select="concat('-', $equiName, '-')"/>

Что выводит?
...
Рейтинг: 0 / 0
14.12.2012, 14:59
    #38079527
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
equiName="lastname", dxlName="F".
Если вставить вашу конструкцию в xsl перед созданием элемента, получается следующее:
Код: xml
1.
2.
3.
4.
5.
6.
<?xml version="1.0" encoding="UTF-8"?>
<ApplicationFile>-
		lastname
	--
		firstname
	-</ApplicationFile>
...
Рейтинг: 0 / 0
15.12.2012, 01:05
    #38080339
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
JacksssonЕсли вставить вашу конструкцию в xsl перед созданием элемента, получается следующее:Откуда в переменной взялись пробелы? Уберите их при формировании значения переменной
...
Рейтинг: 0 / 0
15.12.2012, 01:06
    #38080340
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
RTFM normalize-string()
...
Рейтинг: 0 / 0
16.12.2012, 15:20
    #38081033
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Там видимо табуляция была. Все убрал, ошибка исчезла. Теперь другая проблема - структура конечного документ создается нормально:
Код: xml
1.
2.
3.
4.
5.
<?xml version="1.0" encoding="UTF-8"?>
<ApplicationFile>
   <lastname/>
   <firstname/>
</ApplicationFile>


но нужные значения не подтягиваются и вложенные элементы остаются пустыми. Предполагаю, что дело в конструкции
Код: xml
1.
2.
3.
<xsl:element name="{$equiName}">
	<xsl:value-of select="/document/item[@name='{$dxlName}']/textlist/text"/>
</xsl:element>


Получается что внутри цикла я нахожусь в контексте документа diсtionary.xml, а значения в элементы выбираю из контекста исходного xml. Где то читал, что "если шаблон содержит инструкции xsl:apply-templates или xsl:for-each, которые дополнительно выбирают узлы для обработки, процесс рекурсивно продолжается до тех пор, пока обрабатываемое множество будет содержать хотя бы один узел"©. Как правильно выйти из этой ситуации?
...
Рейтинг: 0 / 0
16.12.2012, 16:39
    #38081084
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
JacksssonКак правильно выйти из этой ситуации?В контексте основного документа
Код: xml
1.
<xsl:variable name="owner" select="/"/>
...
Рейтинг: 0 / 0
16.12.2012, 16:47
    #38081090
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
_Vasilisk_,

а где ее объявить? В цикле или перед?
...
Рейтинг: 0 / 0
16.12.2012, 17:09
    #38081098
Jackssson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
XSLT. Преобразование атрибутов в элементы
Все заработало, спасибо огромное.
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSLT. Преобразование атрибутов в элементы / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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