У меня есть xml, который я хочу преобразовать с помощью XSLT версии 1.0.(Частичный) ввод выглядит следующим образом:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<examples>
<example>
<firstAttribute id="first_attribute_id">
<values>
<value>
<innerValue locale="en-US">EN_US_1_VAL</innerValue>
<innerValue locale="it-IT">IT_IT_1_VAL</innerValue>
</value>
<value>
<innerValue locale="it-IT">IT_IT_2_VAL</innerValue>
</value>
<value>
<innerValue locale="en-US">EN_US_2_VAL</innerValue>
</value>
<value>
<innerValue locale="it-IT">IT_IT_3_VAL</innerValue>
<innerValue locale="en-US">EN_US_3_VAL</innerValue>
</value>
<value>
<innerValue locale="it-IT">IT_IT_4_VAL</innerValue>
</value>
</values>
</firstAttribute>
<extraData>
<secondAttribute id="second_attribute_id">
<values>
<value>
<innerValue locale="en-US">US_1_VAL</innerValue>
<innerValue locale="it-IT">IT_1_VAL</innerValue>
</value>
<value>
<innerValue locale="en-US">US_2_VAL</innerValue>
</value>
<value>
<innerValue locale="it-IT">IT_2_VAL</innerValue>
</value>
<value>
<innerValue locale="en-US">US_3_VAL</innerValue>
<innerValue locale="it-IT">IT_3_VAL</innerValue>
</value>
<value>
<innerValue locale="it-IT">IT_4_VAL</innerValue>
</value>
</values>
</secondAttribute>
</extraData>
</example>
</examples>
</root>
, и я хочу сгруппировать специфичные для локали данные по локали, которая указана в атрибуте локали - ожидаемый вывод :
<root>
<testData>
<test-attributes>
<test-attribute name="first_attribute_id" xml:lang="en-US">
<value>EN_US_1_VAL</value>
<value>EN_US_2_VAL</value>
<value>EN_US_3_VAL</value>
</test-attribute>
<test-attribute name="first_attribute_id" xml:lang="it-IT">
<value>IT_IT_1_VAL</value>
<value>IT_IT_2_VAL</value>
<value>IT_IT_3_VAL</value>
<value>IT_IT_4_VAL</value>
</test-attribute>
</test-attributes>
</testData>
<testData>
<test-attributes>
<test-attribute name="second_attribute_id" xml:lang="en-US">
<value>US_1_VAL</value>
<value>US_2_VAL</value>
<value>US_3_VAL</value>
</test-attribute>
<test-attribute name="second_attribute_id" xml:lang="it-IT">
<value>IT_1_VAL</value>
<value>IT_2_VAL</value>
<value>IT_3_VAL</value>
<value>IT_4_VAL</value>
</test-attribute>
</test-attributes>
</testData>
</root>
Это файл xslt, который я использую, который не дает желаемого результата:
<xsl:stylesheet
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
version="1.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" xalan:indent-amount="2"/>
<xsl:key name="firstLocales" match="firstAttribute/values/value/innerValue" use="@locale"/>
<xsl:key name="secondLocales" match="secondAttribute/values/value/innerValue" use="@locale"/>
<xsl:template match="/">
<xsl:element name="root">
<xsl:for-each select="root/examples/example">
<xsl:element name="testData">
<xsl:element name="test-attributes">
<xsl:for-each select="firstAttribute">
<xsl:for-each select="values/value/innerValue[generate-id() = generate-id(key('firstLocales',@locale)[1])]">
<xsl:element name="test-attribute">
<xsl:attribute name="name"><xsl:value-of select="../../../@id"/></xsl:attribute>
<xsl:attribute name="xml:lang"><xsl:value-of select="@locale"/></xsl:attribute>
<xsl:variable name="CurrentLocale" select="@locale"/>
<xsl:for-each select="../../../values/value/innerValue">
<xsl:if test="@locale = $CurrentLocale">
<xsl:element name="value">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:element>
<xsl:if test="extraData">
<xsl:for-each select="extraData">
<xsl:element name="testData">
<xsl:element name="test-attributes">
<xsl:for-each select="secondAttribute">
<xsl:for-each select="values/value/innerValue[generate-id() = generate-id(key('secondLocales',@locale)[1])]">
<xsl:element name="test-attribute">
<xsl:attribute name="name"><xsl:value-of select="../../../@id"/></xsl:attribute>
<xsl:attribute name="xml:lang"><xsl:value-of select="@locale"/></xsl:attribute>
<xsl:variable name="CurrentLocale" select="@locale"/>
<xsl:for-each select="../../../values/value/innerValue">
<xsl:if test="@locale = $CurrentLocale">
<xsl:element name="value">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Я остановился на решении из здесь , но, очевидно, яЯ делаю что-то не так.Первая часть (где используется firstAttribute) успешно преобразована, однако вторая часть остается пустой - токовый выход :
<root>
<testData>
<test-attributes>
<test-attribute name="first_attribute_id" xml:lang="en-US">
<value>EN_US_1_VAL</value>
<value>EN_US_2_VAL</value>
<value>EN_US_3_VAL</value>
</test-attribute>
<test-attribute name="first_attribute_id" xml:lang="it-IT">
<value>IT_IT_1_VAL</value>
<value>IT_IT_2_VAL</value>
<value>IT_IT_3_VAL</value>
<value>IT_IT_4_VAL</value>
</test-attribute>
</test-attributes>
</testData>
<testData>
<test-attributes/>
</testData>
</root>
Не могли бы вы помочь мне с этим преобразованием - либо исправитьмой файл .xslt или использовать другой подход - я должен придерживаться версии 1.0 XSLT.Заранее спасибо:)