powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / XSLT. Преобразование атрибутов в элементы
23 сообщений из 23, страница 1 из 1
XSLT. Преобразование атрибутов в элементы
    #38063932
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.

Возникла необходимость преобразовать один 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
XSLT. Преобразование атрибутов в элементы
    #38064269
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
XSLT. Преобразование атрибутов в элементы
    #38064276
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
очепяточка, так надо
Код: xml
1.
<xsl:output method="xml" indent="yes" />
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38064448
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо большое. Ваше решение у меня работает, но только если не объявлен в самом 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
XSLT. Преобразование атрибутов в элементы
    #38065386
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jackssson,

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

Честно говоря не совсем понял, о чем речь. Можете пояснить?
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38065576
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jackssson,
Код: xml
1.
2.
3.
4.
<xsl:stylesheet version="1.0"
	...
		xmlns="http://www.lotus.com/dxl"
	...
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38069542
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал немного по другому:
есть первый 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
XSLT. Преобразование атрибутов в элементы
    #38069699
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jackssson,

а первый нужен вообще? второй без него не работает?
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38069821
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
нет, не работает. Там какая то фигня с пространством имен. Решения я не нашел. Если к моему dxl применять только второй xsl, то он не видит вложенных элементов.
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38069942
mage.lan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
XSLT. Преобразование атрибутов в элементы
    #38075685
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Исходный 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
XSLT. Преобразование атрибутов в элементы
    #38077505
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разобрался, как использовать внешний 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
XSLT. Преобразование атрибутов в элементы
    #38078199
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JacksssonПри попытке трансформации пишет, что xsl невалидный.Прямо так и пишет? Или это Ваш вольный перевод сообщения об ошибке?
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38079103
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибка: 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
XSLT. Преобразование атрибутов в элементы
    #38079460
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jacksssonхотя в переменной лежит стринг.Какой?
Код: xml
1.
<xsl:value-of select="concat('-', $equiName, '-')"/>

Что выводит?
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38079527
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
XSLT. Преобразование атрибутов в элементы
    #38080339
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JacksssonЕсли вставить вашу конструкцию в xsl перед созданием элемента, получается следующее:Откуда в переменной взялись пробелы? Уберите их при формировании значения переменной
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38080340
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RTFM normalize-string()
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38081033
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Там видимо табуляция была. Все убрал, ошибка исчезла. Теперь другая проблема - структура конечного документ создается нормально:
Код: 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
XSLT. Преобразование атрибутов в элементы
    #38081084
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JacksssonКак правильно выйти из этой ситуации?В контексте основного документа
Код: xml
1.
<xsl:variable name="owner" select="/"/>
...
Рейтинг: 0 / 0
XSLT. Преобразование атрибутов в элементы
    #38081090
Jackssson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

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


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