我有一个包含两个<video>
元素的XML文件。我的转换通过<videos>
将这些元素合并为一个for-each
元素,并将结果记录为变量variableA
的值。
我可以根据原始数据中<v>
元素的值对转换后的内容进行排序吗?
这是我的代码 http://xsltransform.net/pNmBxZH/8
输入xml
<test>
<video graph="1" potime="1811">
<sec>
<secid>3812907</secid>
<pick>
<vdsecname>A</vdsecname>
<mediadate>24 Apr 2017, 7:45PM IST</mediadate>
<v>240420171945</v>
</pick>
<pick>
<vdsecname>D</vdsecname>
<mediadate>20 Apr 2017, 4:30PM IST</mediadate>
<v>200420171630</v>
</pick>
<pick>
<vdsecname>E</vdsecname>
<mediadate>20 Apr 2017, 3:30PM IST</mediadate>
<v>200420171530</v>
</pick>
</sec>
</video>
<video graph="1" potime="94">
<sec>
<secid>20970242</secid>
<pick>
<vdsecname>B</vdsecname>
<mediadate>23 Apr 2017, 7:30PM IST</mediadate>
<v>230420171930</v>
</pick>
<pick>
<vdsecname>C</vdsecname>
<mediadate>22 Apr 2017, 5:33PM IST</mediadate>
<v>220420171733</v>
</pick>
</sec>
</video>
</test>
使用xsl:sort
我想要变量variableA
。v
标签中有值使用此值我要对变量进行排序
预期输出
<videos>
<pick>
<vdsecname>A</vdsecname>
<mediadate>24 Apr 2017, 7:45PM IST</mediadate>
<v>240420171945</v>
</pick>
<pick>
<vdsecname>B</vdsecname>
<mediadate>23 Apr 2017, 7:30PM IST</mediadate>
<v>230420171930</v>
</pick>
<pick>
<vdsecname>C</vdsecname>
<mediadate>22 Apr 2017, 5:33PM IST</mediadate>
<v>220420171733</v>
</pick>
<pick>
<vdsecname>D</vdsecname>
<mediadate>20 Apr 2017, 4:30PM IST</mediadate>
<v>200420171630</v>
</pick>
<pick>
<vdsecname>E</vdsecname>
<mediadate>20 Apr 2017, 3:30PM IST</mediadate>
<v>200420171530</v>
</pick>
</videos>
我希望<pick>
中生成的<videos>
元素按其<v>
子项(从输入文档中复制)的降序排序,如图所示。
这是我目前的转型:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<hmtl>
<head>
<title>New Version!</title>
</head>
<xsl:variable name="variableA">
<videos>
<xsl:for-each select="test/video">
<xsl:copy-of select="sec/pick"/>
</xsl:for-each>
</videos>
</xsl:variable>
<xsl:copy-of select="$variableA"/>
</hmtl>
</xsl:template>
</xsl:transform>
答案 0 :(得分:0)
可以稍微调整一下for-each和sort会有所帮助。请告诉我们。
<xsl:for-each select="test/video/sec/pick">
<xsl:sort select="vdsecname" data-type="text" order="ascending"/>
<xsl:copy-of select="."/>
</xsl:for-each>
答案 1 :(得分:0)
您当然可以使用xsl:sort
来生成所需的输出。既然你知道这个元素,但仍然会问这个问题,我想你试图使用它但却没有得到你想要的结果。鉴于样式表的当前结构,这不足为奇。
要理解xsl:sort
最重要的事情之一是它导致排序的原因,这是apply-templates
或{{1}选择的输入节点与之关联的元素。 for-each
导致输入节点按其描述的顺序进行处理,上下文的当前节点列表也以这种方式排序。这是您编写的样式表的问题,因为它是您要排序的xsl-sort
元素,而是您要迭代的<pick>
元素。
此外,目前还不清楚为什么要在这里引入变量。我怀疑你有误解,你可能会在设置它们之后对该变量的内容进行排序,但XSLT不会那样工作。如果该值是节点集,那么您可以在将变换应用于该值时进行排序。但是,如果您只使用变量值一次,那么您根本不需要变量 - 您也可以直接表达变换。
然后,这是样式表(在XSLT 1.0中)的变体,它产生预期的输出结构:
<video>
您还可以为排序键指定更复杂的表达式,以及多个排序键。在后一种情况下,密钥从最重要到最不重要。例如,如果您的<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<hmtl>
<head>
<title>New Version!</title>
</head>
<videos>
<!-- iterate over (all) the <pick> elements, in sorted order -->
<xsl:for-each select="test/video/sec/pick">
<!-- sort keys must come first -->
<xsl:sort select="v" data-type="number" order="descending" />
<xsl:copy-of select="."/>
</xsl:for-each>
</videos>
</hmtl>
</xsl:template>
</xsl:stylesheet>
元素旨在被解释为编码与<v>
元素相同日期的结构化数字字符串,则按它们所代表的日期的降序排序,那么您可以替换它样式表片段代替上面相应的一个:
<mediadate>