这篇文章是XSLT transforming an xml的扩展名。
在这个结果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>
<str name="rows">2</str>
<str name="start">1</str>
</lst>
</lst>
<result name="response" numFound="1" start="0">
<doc>
<str name="query">what</str>
<arr name="suggestion">
<str>what1</str>
<str>what2</str>
<str>what3</str>
<str>what4</str>
<str>what5</str>
</arr>
</doc>
</result>
</response>
通过使用前面提到的上一篇文章中提到的xsl,我可以得到输出,
<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>
<!--str name="rows">
2</str>
<str name="start">1</str-->
</lst>
</lst>
<result name="response" numfound="5" start="0">
<doc>
<str name="query">what</str>
<str name="suggestion">what1</str>
<float name="score">100</float>
</doc>
<doc>
<str name="query">what</str>
<str name="suggestion">what2</str>
<float name="score">200</float>
</doc>
<doc>
<str name="query">what</str>
<str name="suggestion">what3</str>
<float name="score">300</float>
</doc>
<doc>
<str name="query">what</str>
<str name="suggestion">what4</str>
<float name="score">400</float>
</doc>
<doc>
<str name="query">what</str>
<str name="suggestion">what5</str>
<float name="score">500</float>
</doc>
</result>
</response>
当我给出start = 2时,我希望在遗漏0和第一个建议之后从what3开始建议。
同样,当我给行= 1时,这意味着我只能得到一个从“开始”位置开始的结果
另外,我想确保拥有行的默认值并启动。因此,在浏览网络上,我可以找到这篇文章:http://remysharp.com/2008/08/15/how-to-default-a-variable-in-xslt/
是否有更好的方法为变量指定默认值,比如使用默认属性?我尝试使用默认属性。但似乎没有使用它。
此外,我可以看到<xsl:for-each>
迭代一个数组。但是我不知道如何让它具有起始值和结束值,比如如果start是2而行是2那么我想要一些像这样的东西,
<xsl:for-each select="counter" start="$start" end = "$end">
<doc>
<str name="query">what</str>
<str name="suggestion"><xsl:value-of select="//arr[@name='suggestion'][start]"</str>
</doc>
</xsl:for-each>
请提出任何建议......
我的解决方案:
尝试了更多并且最终乐于学习关于xsl的一些事情:)感谢Dimitre和G_H(来自之前的帖子)..
XSL已创建:
<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="/response/result">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:attribute name="numFound"><xsl:value-of select="count(doc/arr[@name='suggestion']/str)" /></xsl:attribute>
<xsl:apply-templates select="doc/arr[@name='suggestion']" />
</xsl:copy>
</xsl:template>
<xsl:template match="arr[@name='suggestion']">
<xsl:variable name="rows" as="xs:integer">
<xsl:choose>
<xsl:when test="/response/lst/lst/str[@name='rows']"><xsl:value-of select="/response/lst/lst/str[@name='rows']"/></xsl:when>
<xsl:otherwise>10</xsl:otherwise> <!-- default value -->
</xsl:choose>
</xsl:variable>
<xsl:variable name="start" as="xs:integer">
<xsl:choose>
<xsl:when test="/response/lst/lst/str[@name='start']"><xsl:value-of select="/response/lst/lst/str[@name='rows']"/></xsl:when>
<xsl:otherwise>0</xsl:otherwise> <!-- default value -->
</xsl:choose>
</xsl:variable>
<xsl:for-each select="str">
<xsl:if test="position()-1 >= $start and position() <= $rows+$start">
<doc>
<xsl:copy-of select="parent::node()/preceding-sibling:: str[@name='query']" />
<xsl:variable name="nameAttributeValue" select="parent::node()/@name" />
<xsl:element name="str"><xsl:attribute name="name"><xsl:value-of select="$nameAttributeValue" /></xsl:attribute><xsl:value-of select="." /></xsl:element>
<float name="score">
<xsl:value-of select="100*position()"/>
</float>
</doc>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输入:
<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>
<str name="rows">2</str>
<str name="start">2</str>
</lst>
</lst>
<result name="response" numFound="1" start="0">
<doc>
<str name="query">what</str>
<arr name="suggestion">
<str>what1</str>
<str>what2</str>
<str>what3</str>
<str>what4</str>
<str>what5</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>
<str name="rows">2</str>
<str name="start">2</str>
</lst>
</lst>
<result name="response" numfound="5" start="0">
<doc>
<str name="query">what</str>
<str name="suggestion">what3</str>
<float name="score">300</float>
</doc>
<doc>
<str name="query">what</str>
<str name="suggestion">what4</str>
<float name="score">400</float>
</doc>
</result>
</response>
最后,我可能需要根据给定的文档数更改numfound参数。 再次感谢您的指导:)
答案 0 :(得分:1)
这是一个产生想要结果的XSLT 2.0转换:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pdefStart" as="xs:integer" select="1"/>
<xsl:param name="pdefRows" as="xs:integer" select="9999999"/>
<xsl:variable name="vStart" as="xs:integer" select=
"(/*/lst/lst/str[@name='start'],
$pdefStart
)
[1]
"/>
<xsl:variable name="vRows" as="xs:integer" select=
"(/*/lst/lst/str[@name='rows'],
$pdefRows
)
[1]
"/>
<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
[position() ge $vStart
and
position() lt $vStart + $vRows
]
)}"
start="{$vStart}">
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match=
"arr[@name='suggestion']/str
[position() ge $vStart
and
position() lt $vStart + $vRows
]">
<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="str"/>
</xsl:stylesheet>
应用于此XML文档(基于提供的,但rows
和start
的“有趣”值更多):
<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>
<str name="rows">3</str>
<str name="start">2</str>
</lst>
</lst>
<result name="response" numFound="1" start="0">
<doc>
<str name="query">what</str>
<arr name="suggestion">
<str>what1</str>
<str>what2</str>
<str>what3</str>
<str>what4</str>
<str>what5</str>
</arr>
</doc>
</result>
</response>
产生了想要的正确结果:
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params"/>
</lst>
<result numFound="3" start="2">
<doc>
<str name="query">what</str>
<str>what2</str>
<float name="score">200</float>
</doc>
<doc>
<str name="query">what</str>
<str>what3</str>
<float name="score">300</float>
</doc>
<doc>
<str name="query">what</str>
<str>what4</str>
<float name="score">400</float>
</doc>
</result>
</response>
转换中的默认值设置为,如果XML文档中未指定start
,我们假设为start = 1
,如果没有rows
如果指定了rows = 9999999
,也就是说,在默认情况下,我们希望获得与文档中一样多的str
个元素。
以下是一个示例:
<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="query">what</str>
<arr name="suggestion">
<str>what1</str>
<str>what2</str>
<str>what3</str>
<str>what4</str>
<str>what5</str>
</arr>
</doc>
</result>
</response>
此文档没有rows
和start
,在使用上述转换进行处理时,会使用默认值,生成:
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">1</int>
<lst name="params"/>
</lst>
<result numFound="5" start="1">
<doc>
<str name="query">what</str>
<str>what1</str>
<float name="score">100</float>
</doc>
<doc>
<str name="query">what</str>
<str>what2</str>
<float name="score">200</float>
</doc>
<doc>
<str name="query">what</str>
<str>what3</str>
<float name="score">300</float>
</doc>
<doc>
<str name="query">what</str>
<str>what4</str>
<float name="score">400</float>
</doc>
<doc>
<str name="query">what</str>
<str>what5</str>
<float name="score">500</float>
</doc>
</result>
</response>
最后,请注意:为了获得最大的灵活性,默认值被指定为全局参数,并可以从外部传递到转换。