Решение XPath 1.0 с одним выражением, если вообще возможно, будет сложно написать и понять .
Вот простое решение XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kFollowing" match="dd"
use="generate-id(preceding-sibling::dt[1])"/>
<xsl:template match="dl">
{ <xsl:apply-templates select="dt"/> }
</xsl:template>
<xsl:template match="dt">
<xsl:text/>'<xsl:value-of select="."/>' : [ <xsl:text/>
<xsl:apply-templates select=
"key('kFollowing', generate-id())"/>
<xsl:text> ]</xsl:text>
<xsl:if test="not(position()=last())">, </xsl:if>
</xsl:template>
<xsl:template match="dd">
<xsl:text/>'<xsl:value-of select="."/>'<xsl:text/>
<xsl:if test="not(position()=last())">, </xsl:if>
</xsl:template>
</xsl:stylesheet>
, когда это преобразование применяется к предоставленному документу XML:
<dl>
<dt>Section One</dt>
<dd>Child one</dd>
<dd>Child one.2</dd>
<dt>Section Two</dt>
<dd>Child two</dd>
</dl>
желаемый, правильный результат:
{ 'Section One' : [ 'Child one', 'Child one.2' ], 'Section Two' : [ 'Child two' ] }
Объяснение : xsl:key
определено и используется для захвата отношения 1 -> много между dt
и непосредственно следующими элементами родственного элемента dt
.