Как создать свои теги через XSLT
Есть xml:
<?xml version="1.0" encoding="utf-8"?>
<Records count="2">
<Metadata>
<FieldDefinitions>
<FieldDefinition id="123" guid="ef0ce125-ca87-4f13-92f6-988eefcb389e" name="Наименование1" alias="Наименование1" />
<FieldDefinition id="456" guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf" name="Наименование2" alias="Наименование2" />
<FieldDefinition id="789" guid="62c6d1d3-8b49-4128-a758-ec383894c432" name="Наименование3" alias="Наименование3" />
</FieldDefinitions>
</Metadata>
<LevelCounts>
<LevelCount id="111" guid="ac53e54a-b5b3-4f92-aba1-b67e4156a868" count="2" />
</LevelCounts>
<Record contentId="253172" levelId="329" levelGuid="ad31d387-af1a-4642-9bbf-719f9b3ab251" moduleId="222" parentId="0">
<Field id="123" guid="ef0ce125-ca87-4f13-92f6-988eefcb389e" type="6">1223445</Field>
<Field id="456" guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf" type="1">Имя чего нибудь</Field>
<Field id="789" guid="62c6d1d3-8b49-4128-a758-ec383894c432" type="1">аааааааа</Field>
</Record>
<Record contentId="253195" levelId="329" levelGuid="ad31d387-af1a-4642-9bbf-719f9b3ab251" moduleId="222" parentId="0">
<Field id="123" guid="ef0ce125-ca87-4f13-92f6-988eefcb389e" type="6">1233</Field>
<Field id="456" guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf" type="1">Имя чего нибудь2</Field>
<Field id="789" guid="62c6d1d3-8b49-4128-a758-ec383894c432" type="1">бббббббббб</Field>
</Record>
</Records>
Как преобразовать это в это?
<?xml version="1.0" encoding="utf-8"?>
<Records>
<Record>
<id>1223445</id>
<name>Имя чего нибудь</name>
<comment>аааааааа</comment>
</Record>
<Record>
<id>1233</id>
<name>Имя чего нибудь2</name>
<comment>бббббббббб</comment>
</Record>
</Records>
Я использую вот такой xslt:
<?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="/Records">
<Records>
<xsl:apply-templates select="Record"/>
</Records>
</xsl:template>
<xsl:template match="Record">
<Record>
<xsl:for-each select="Field">
<xsl:element name="{/Records/Metadata/FieldDefinitions/FieldDefinition[@guid=current()/@guid]/@alias}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</Record>
</xsl:template>
</xsl:stylesheet>
мне нужно сделать собственные наименования полей, заполнить их по guid. Т.к. в системе могут измениться наименования, поэтому нужно сделать привязку по guid. Но guid использовать в качестве наименования нельзя(XSLT интерпретатор ругается на это).
Ответы (2 шт):
Автор решения: Yitzhak Khabinsky
→ Ссылка
Вот решение на основе XSLT 2.0 или более поздней версии.
XSLT использует идею Lookup для присвоения желаемых имен XML-элементов.
Полезная ссылка для XSLT 3.0 для Python
Вы можете скачать Saxon Home Edition (HE) бесплатно.
Входной XML
<?xml version="1.0" encoding="utf-8"?>
<Records count="2">
<Metadata>
<FieldDefinitions>
<FieldDefinition id="123"
guid="ef0ce125-ca87-4f13-92f6-988eefcb389e"
name="Наименование1" alias="Наименование1"/>
<FieldDefinition id="456"
guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf"
name="Наименование2" alias="Наименование2"/>
<FieldDefinition id="789"
guid="62c6d1d3-8b49-4128-a758-ec383894c432"
name="Наименование3" alias="Наименование3"/>
</FieldDefinitions>
</Metadata>
<LevelCounts>
<LevelCount id="111" guid="ac53e54a-b5b3-4f92-aba1-b67e4156a868"
count="2"/>
</LevelCounts>
<Record contentId="253172" levelId="329"
levelGuid="ad31d387-af1a-4642-9bbf-719f9b3ab251" moduleId="222"
parentId="0">
<Field id="123" guid="ef0ce125-ca87-4f13-92f6-988eefcb389e" type="6">1223445</Field>
<Field id="456" guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf" type="1">Имя чего нибудь</Field>
<Field id="789" guid="62c6d1d3-8b49-4128-a758-ec383894c432" type="1">аааааааа</Field>
</Record>
<Record contentId="253195" levelId="329"
levelGuid="ad31d387-af1a-4642-9bbf-719f9b3ab251" moduleId="222"
parentId="0">
<Field id="123" guid="ef0ce125-ca87-4f13-92f6-988eefcb389e" type="6">1233</Field>
<Field id="456" guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf" type="1">Имя чего нибудь2</Field>
<Field id="789" guid="62c6d1d3-8b49-4128-a758-ec383894c432" type="1">бббббббббб</Field>
</Record>
</Records>
XSLT 2.0
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="lookup" match="row" use="@alias"/>
<xsl:variable name="lookup">
<row alias="Наименование1" elem="id"/>
<row alias="Наименование2" elem="name"/>
<row alias="Наименование3" elem="comment"/>
</xsl:variable>
<xsl:template match="/Records">
<xsl:copy>
<xsl:for-each select="Record">
<xsl:copy>
<xsl:for-each select="Field">
<xsl:variable name="alias"
select="/Records/Metadata/FieldDefinitions/FieldDefinition[@guid=current()/@guid]/@alias"/>
<xsl:element name="{key('lookup', $alias, $lookup)/@elem}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Результат
<?xml version='1.0' encoding='UTF-8' ?>
<Records>
<Record>
<id>1223445</id>
<name>Имя чего нибудь</name>
<comment>аааааааа</comment>
</Record>
<Record>
<id>1233</id>
<name>Имя чего нибудь2</name>
<comment>бббббббббб</comment>
</Record>
</Records>
Автор решения: Don Perez
→ Ссылка
Мой конечный результат получился таким:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="lookup" match="row" use="@guid"/>
<xsl:variable name="lookup">
<row guid="ef0ce125-ca87-4f13-92f6-988eefcb389e" elem="id"/>
<row guid="524f9b49-316e-4dd8-ae49-7a3e58b67adf" elem="name"/>
<row guid="62c6d1d3-8b49-4128-a758-ec383894c432" elem="comment"/>
</xsl:variable>
<xsl:template match="/Records">
<xsl:copy>
<xsl:for-each select="Record">
<xsl:copy>
<xsl:for-each select="Field">
<xsl:variable name="guid"
select="/Records/Metadata/FieldDefinitions/FieldDefinition[@guid=current()/@guid]/@guid"/>
<xsl:element name="{key('lookup', $guid, $lookup)/@elem}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>