Xml 如何在xslt中使用xsl:sort?
我有一个包含两个Xml 如何在xslt中使用xsl:sort?,xml,sorting,xslt,xslt-1.0,Xml,Sorting,Xslt,Xslt 1.0,我有一个包含两个元素的XML文件。My transform通过每个的一个,将这些元素合并为一个元素,并将结果记录为变量variableA的值 我是否可以根据原始数据中元素的值对转换后的内容进行排序 这是我的密码 输入xml <test> <video graph="1" potime="1811"> <sec> <secid>3812907</secid> <
元素的XML文件。My transform通过每个的一个,将这些元素合并为一个
元素,并将结果记录为变量variableA
的值
我是否可以根据原始数据中
元素的值对转换后的内容进行排序
这是我的密码
输入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>
我希望
中生成的
元素按其
子元素(从输入文档复制)降序排序,如图所示
以下是我当前的转换:
<?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>
新版本!
可能需要对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>
您当然可以使用xsl:sort
生成所需的输出。既然你知道这个元素,但仍然问这个问题,我想你试着使用它,但没有得到你想要的结果。考虑到样式表的当前结构,这并不奇怪
关于xsl:sort
需要了解的最重要的事情之一是它导致排序的原因,即apply templates
或为与其关联的每个
元素选择的输入节点<代码>xsl排序
使输入节点按照它描述的顺序进行处理,上下文的当前节点列表也以这种方式进行排序。这对于您编写的样式表来说是一个问题,因为您要排序的是
元素,而您要迭代的是
元素
此外,不清楚为什么在这里引入变量。我怀疑您误解了可能会在设置变量后对其内容进行排序,但XSLT并不是这样工作的。如果该值是一个节点集,则可以在对该值应用变换时进行排序。但是,如果只使用变量的值一次,那么就根本不需要变量——最好直接表示转换
下面是样式表(XSLT 1.0中)的一个变体,它生成预期的输出结构:
<?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>
新版本!
您还可以为排序键以及多个排序键指定更复杂的表达式。在后一种情况下,键从最重要到最不重要进行解释。例如,如果您的
元素被解释为结构化数字字符串,编码与
元素相同的日期,并按它们所代表的日期降序排序,那么您可以用此样式表片段代替上面相应的片段:
<xsl:for-each select="test/video/sec/pick">
<!-- sort keys must come first -->
<xsl:sort select="substring(v, 5, 4)" data-type="number" order="descending" />
<xsl:sort select="substring(v, 3, 2)" data-type="number" order="descending" />
<xsl:sort select="substring(v, 1, 2)" data-type="number" order="descending" />
<xsl:sort select="substring(v, 9, 4)" data-type="number" order="descending" />
<xsl:copy-of select="."/>
</xsl:for-each>
这一点和其他问题一样不清楚。为什么需要变量呢?为什么不简单地对源XML的节点进行排序并将结果直接写入输出?您已经提供了XSLT 2.0样式表,但是您已经标记了[XSLT-1.0]。您实际上打算使用哪个版本的XSLT?@JohnBollinger请不要对问题添加您自己的解释。@michael.hor257k,我们只能对问题进行自己的解释。编辑问题以改进问题完全符合SO的规范,如果OP认为编辑不适当地改变了问题的性质,那么他完全有能力将其回滚或进一步编辑。当然,这也是你的特权,但我不清楚你在这里到底做了什么。你删除了和variableA语法,得到了相同的结果。可能会简化您的代码。虽然这确实会产生类似于OP中所示的输出,但我怀疑这只是巧合。v
值以ddmmyyyhhmm
格式清楚地表示日期和时间-我认为很明显,它们需要按年、月、日和时间顺序分别排序(正如我在这个问题的第一次迭代中向OP建议的那样)。现在谁来解释这个问题,@michael.hor257k?但你可能是对的。我已经更新了我的答案来解决这个问题,但我已经清楚地提出了我自己的解释。如果我试图通过编辑问题来强迫每个人接受,那么你的观点是正确的。顺便说一句,你可以将最后两个组合到子字符串(v,9,4)
。
<xsl:for-each select="test/video/sec/pick">
<!-- sort keys must come first -->
<xsl:sort select="substring(v, 5, 4)" data-type="number" order="descending" />
<xsl:sort select="substring(v, 3, 2)" data-type="number" order="descending" />
<xsl:sort select="substring(v, 1, 2)" data-type="number" order="descending" />
<xsl:sort select="substring(v, 9, 4)" data-type="number" order="descending" />
<xsl:copy-of select="."/>
</xsl:for-each>