2010-02-16 82 views
3

我想知道是否可以先排序某些元素并将它们(已排序)存储在变量中。我需要引用他们认为的XSLT,这就是为什么我想将它们存储在一个变量中。如何对元素进行排序并将它们存储在变量中XSLT

我试图做到以下几点,但它似乎没有工作

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 

<xsl:variable name="deposits"> 
    <xsl:for-each select="/BookingCostings/MultiDeposits"> 
    <xsl:sort select="substring(@DepositDate, 1, 4)" /> 
    <xsl:sort select="substring(@DepositDate, 6, 2)" /> 
    <xsl:sort select="substring(@DepositDate, 9, 2)" /> 
</xsl:for-each> 
</xsl:variable> 

我试图通过@DepositDate格式的元素进行排序“YYYY-MM-DD”,并将其储存所有在$deposits变量中。这样以后,我可以使用$deposits[1]访问它们。

我将不胜感激任何帮助和提示!

非常感谢!

+0

你的问题表明你可能是试图解决一个问题一个更大规模走错了路。 *为什么*你想将一个已排序的节点集存储在一个变量中?你究竟想要做什么? (“我想将它们作为'$ deposits [1]'”访问它们并不是我正在寻找的答案。) – Tomalak 2010-02-16 12:12:18

+0

Tomalak,不幸的是,我正在处理严重结构化的XML。有一些必须按顺序排列的配置文件,也需要在结果文件的不同部分。没有确定存款顺序的属性,我决定不依靠这个位置。这就是为什么我决定对它们进行分类和存储的原因,这样我就可以在需要的时候轻松地将所有这些特定分支引用。 希望有道理? – DashaLuna 2010-02-17 09:04:40

+0

是的。有时候就是这样。思考一个中介转型,合理地重构错误投入,然后建立你的最终转变?从长远来看,这可能是值得的。 – Tomalak 2010-02-17 17:45:13

回答

3

首先,在你的变量声明,你需要做一些事情来创建新节点。严格地说,你并没有对它们进行排序,而只是按给定顺序阅读它们。我认为你需要添加一些xsl:copy命令。

<xsl:variable name="deposits"> 
    <xsl:for-each select="/BookingCostings/MultiDeposits"> 
    <xsl:sort select="substring(@DepositDate, 1, 4)" /> 
    <xsl:sort select="substring(@DepositDate, 6, 2)" /> 
    <xsl:sort select="substring(@DepositDate, 9, 2)" /> 
    <xsl:copy-of select=".|@*" /> 
</xsl:for-each> 
</xsl:variable> 

这是创建一个“节点集”,但要访问它,您需要在XSLT中使用扩展功能。您使用哪一个取决于您使用的XSLT处理器。在我将要提供的例子中,我使用了微软的一个。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt" version="1.0"> 

然后,访问节点的变量,你可以做这样的事情

<xsl:value-of select="ms:node-set($deposits)/MultiDeposits[1]/@DepositDate" /> 

这里是一个节点集读了一篇好文章

Xml.com article on Node-Sets

+2

Tim在你的for内部是正确的,如果你想填充变量,你需要输出一些东西,所以在for-each中使用。然而,变量的类型不是节点集,而是结果树片段。只有通过调用变量的扩展函数,结果树片段才能转换为可应用XPath的节点集。 – 2010-02-16 12:05:57

+0

谢谢你们!是的,我绝对需要。蒂姆谢谢你的文章,这是有帮助的。 马丁,你知道任何一个很好的阅读树碎片和不同的函数如何在文档上工作吗?或者就此而言,有关XSLT的一般信息?我真的很感激它。只是试图更好地理解它:) – DashaLuna 2010-02-17 09:15:37

0

猜想(没有开发ENV手):

添加 <xsl:value-of select="." />

收盘前</xsl:for-each>

4
  1. 使用XSLT version 2.0你可以使用perform-sort并告诉你的变量类型为a使用MultiDeposits序列as keywordas="element(MultiDeposits)+“)
  2. 由于您的数据已经为yyyy-MM-DD你能避免使用subtring来获取日期的各个部分,然后直接在现场使用的排序

使用此示例的xml:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<BookingCostings> 
    <MultiDeposits depositDate="2001-10-09">1</MultiDeposits> 
    <MultiDeposits depositDate="1999-10-09">2</MultiDeposits> 
    <MultiDeposits depositDate="2010-08-09">3</MultiDeposits> 
    <MultiDeposits depositDate="2010-07-09">4</MultiDeposits> 
    <MultiDeposits depositDate="1998-01-01">5</MultiDeposits> 
</BookingCostings> 

和使用XSLT版本2。0片:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
<html> 
    <body> 

    <xsl:variable name="deposits" as="element(MultiDeposits)+"> 
    <xsl:perform-sort select="BookingCostings/MultiDeposits"> 
    <xsl:sort select="@depositDate"/> 
    </xsl:perform-sort> 
    </xsl:variable> 

    first date:<xsl:value-of select="$deposits[1]/@depositDate"/>, 
    last date:<xsl:value-of select="$deposits[last()]/@depositDate"/> 

    </body> 
</html> 
</xsl:template> 

</xsl:stylesheet> 

的输出继电器将是:

first date:1998-01-01, last date:2010-08-09 
+0

谢谢帕特里克。我假设在XSLT 1.0中as =“element(MultiDeposits)+”是不可能的? 不幸的是,我没有格式为yyyy-mm-dd的日期。在子串函数之前,我在每个排序语句中使用函数。我没有提到它简化代码。我试图在排序语句之前将整个日期转换为yyyy-mm-dd,但显然排序指令必须是第一个。所以是的。 谢谢你的回应:) – DashaLuna 2010-02-17 09:18:50

+0

不幸的是,它只有2.0。 – Patrick 2010-02-17 10:27:29

相关问题