Я хочу объединить элементы с одинаковым id в один элемент.Результирующий элемент должен иметь первый непустой элемент из группы элементов.Если в группе элементов нет непустого элемента, то сам элемент игнорируется в группе элементов и не должен присутствовать в результирующем элементе.
Образец XML-ввода:
<?xml version="1.0" encoding="UTF-8" ?>
<shiporder orderid="orderid106">
<orderperson id="123">orderperson107</orderperson>
<shipto>
<name>name108</name>
<address>address109</address>
<city>city110</city>
<country>country111</country>
</shipto>
<!--Item Group 100-->
<item>
<id>100</id>
<title>
<first>
<a></a>
</first>
<last>item100_lastTitle1</last>
</title>
<note></note>
<quantity></quantity>
</item>
<item>
<id>100</id>
<title>
<first>
<a>a_100_2</a>
</first>
<last>item100_lastTitle2</last>
</title>
<note>note100_2</note>
<quantity></quantity>
</item>
<item>
<id>100</id>
<title>
<first>
<a att1="abc" att2='cde'>a_100_3</a>
</first>
<last id="1" attr="2">item100_lastTitle3</last>
</title>
<note>note100_3</note>
<quantity>1</quantity>
</item>
<!--Item Group 101-->
<item>
<id>101</id>
<title>
<first>
<a>a_101_1</a>
</first>
<last></last>
</title>
<note>note101_1</note>
<quantity>10</quantity>
</item>
<item>
<id>101</id>
<title>
<first>
<a>a_101_2</a>
</first>
<last>item101_lastTitle2</last>
</title>
<note>note101_2</note>
<quantity>5</quantity>
</item>
<!--Item Group 103-->
<item>
<id>103</id>
<title>
<first>
<a>a_103_2</a>
</first>
<last>item103_lastTitle2</last>
</title>
<note>note103_1</note>
<quantity></quantity>
</item>
</shiporder>
ОбразецВывод XML:
<?xml version = '1.0' encoding = 'UTF-8'?>
<shiporder orderid="orderid106">
<item>
<id>100</id>
<title>
<first>
<a>a_100_2</a>
</first>
<last>item100_lastTitle1</last>
</title>
<note>note100_2</note>
<quantity>6</quantity>
</item>
<item>
<id>101</id>
<title>
<first>
<a>a_101_1</a>
</first>
<last>item101_lastTitle2</last>
</title>
<note>note101_1</note>
<quantity>10</quantity>
</item>
<item>
<id>103</id>
<title>
<first>
<a>a_103_2</a>
</first>
<last>item103_lastTitle2</last>
</title>
<note>note103_1</note>
</item>
</shiporder>
Я попытался с помощью следующего XSL-кода получить вышеуказанный вывод:
<?xml version="1.0" encoding="windows-1252" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/shiporder">
<shiporder>
<xsl:if test="@orderid">
<xsl:attribute name="orderid">
<xsl:value-of select="@orderid"/>
</xsl:attribute>
</xsl:if>
<!-- Grouping each item based on its ID element value-->
<xsl:for-each-group select="item" group-by="id">
<item-group>
<!-- For Each group search for first non empty child element-->
<xsl:for-each select="current-group()[id/text()][1]">
<xsl:copy-of select="id"/>
</xsl:for-each>
<title>
<first>
<!-- for 'a' element -->
<xsl:variable name="temp1">
<xsl:for-each select="current-group()/title/first[a/text()][1]">
<elm>
<xsl:copy-of select="a"/>
</elm>
</xsl:for-each>
</xsl:variable>
<xsl:copy-of select="$temp1/elm[1]/a"/>
</first>
<!-- for 'last' element -->
<xsl:variable name="temp2">
<xsl:for-each select="current-group()/title[last/text()][1]">
<elm>
<xsl:copy-of select="last"/>
</elm>
</xsl:for-each>
</xsl:variable>
<xsl:copy-of select="$temp2/elm[1]/last"/>
</title>
<!-- for 'note' element -->
<xsl:for-each select="current-group()[note/text()][1]">
<xsl:copy-of select="note"/>
</xsl:for-each>
<!-- for 'quantity' element -->
<xsl:for-each select="current-group()[quantity/text()][1]">
<xsl:copy-of select="quantity"/>
</xsl:for-each>
</item-group>
</xsl:for-each-group>
</shiporder>
</xsl:template>
</xsl:stylesheet>
Код работает нормально, но хуже всего то, что я не смог его сделатьобобщать.Для каждого элемента в элементе мне нужно написать xsl-код, специфичный для xpath конкретного элемента.Я даже не мог написать код в терминах пользовательских шаблонов.
Я нашел уже отвеченный вопрос в заголовке " Рекурсивно комбинировать идентичные элементы в XSLT ".Но я не могу настроить его в соответствии с моими требованиями.
У меня есть сотни таких дочерних или наследственных элементов под каждым элементом, и глубина каждого элемента произвольна.Очень смешно писать xsl-код, соответствующий каждому из этих потомков или потомков.Может ли кто-нибудь из экспертов помочь мне написать общий xsl-код (независимо от количества элементов, а также его глубины) или оптимизировать существующий код?
Заранее спасибо,Касир