Вот решение для комментария ОП, который обновляет вопрос:
Это преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="result">
<result numFound="{count(doc/arr/str)}">
<xsl:apply-templates select="@*[not(name()='numFound')]"/>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="arr[@name='suggestion']/str">
<doc>
<xsl:copy-of select="../../str"/>
<xsl:copy-of select="."/>
</doc>
</xsl:template>
<xsl:template match="doc|doc/arr">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="doc/str "/>
</xsl:stylesheet>
при применении к следующему (при условиив комментарии ОП) XML-документ :
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params">
<str name="indent">on</str>
<str name="q">"what"</str>
</lst>
</lst>
<result name="response" numFound="1" start="0">
<doc>
<str name="q">what</str>
<arr name="suggestion">
<str>what1</str>
<str>what2</str>
</arr>
</doc>
</result>
</response>
дает требуемый, правильный результат :
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params">
<str name="indent">on</str>
<str name="q">"what"</str>
</lst>
</lst>
<result numFound="2" name="response" start="0">
<doc>
<str name="q">what</str>
<str>what1</str>
</doc>
<doc>
<str name="q">what</str>
<str>what2</str>
</doc>
</result>
</response>
Обновление :
В обновлении своего вопроса ОП запросил:
Может кто-нибудь сказать, могу ли я добавить в выходной документ поле с именем <float name="score">
, которое будет увеличено на 100с каждым документом?
Этого чрезвычайно легко достичь .Мы добавляем всего три строки кода к существующему преобразованию:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="result">
<result numFound="{count(doc/arr/str)}">
<xsl:apply-templates select="@*[not(name()='numFound')]"/>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="arr[@name='suggestion']/str">
<doc>
<xsl:copy-of select="../../str"/>
<xsl:copy-of select="."/>
<float name="score">
<xsl:value-of select="100*position()"/>
</float>
</doc>
</xsl:template>
<xsl:template match="doc|doc/arr">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="doc/str "/>
</xsl:stylesheet>
Когда это преобразование применяется к этому документу XML :
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params">
<str name="indent">on</str>
<str name="q">"what"</str>
</lst>
</lst>
<result name="response" numFound="1" start="0">
<doc>
<str name="q">what</str>
<arr name="suggestion">
<str>what1</str>
<str>what2</str>
<str>what3</str>
</arr>
</doc>
</result>
</response>
хотел, правильный результат получается :
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params">
<str name="indent">on</str>
<str name="q">"what"</str>
</lst>
</lst>
<result numFound="3" name="response" start="0">
<doc>
<str name="q">what</str>
<str>what1</str>
<float name="score">100</float>
</doc>
<doc>
<str name="q">what</str>
<str>what2</str>
<float name="score">200</float>
</doc>
<doc>
<str name="q">what</str>
<str>what3</str>
<float name="score">300</float>
</doc>
</result>
</response>