1

我试图搜索类似的问题并找到了这个这个..但它们特别不符合我的要求..

示例 XML 输入尝试使用:

<TestMessage>
    <INSTest>
        <INSClaim Id="1-TEST">
            <Id>1-TEST</Id>
            <INSTestElements>
                <INSTestElement>
                    <SortingOrder>2</SortingOrder>
                    <Created>12/29/2012 13:45:58</Created>
                    <Id>1-Element1</Id>
                </INSTestElement>
                <INSTestElement>
                    <SortingOrder>3</SortingOrder>
                    <Created>12/31/2012 14:45:58</Created>
                    <Id>1-Element2</Id>
                </INSTestElement>
                <INSTestElement>
                    <SortingOrder>1</SortingOrder>
                    <Created>12/31/2011 21:45:58</Created>
                    <Id>1-Element3</Id>
                </INSTestElement>
            </INSTestElements>
        </INSClaim>
    </INSTest>
</TestMessage>

XSL 输入尝试使用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="INSTestElements">
        <xsl:copy>
            <xsl:for-each select="INSTestElement">
                <xsl:variable name="created"><xsl:value-of select="Created"/></xsl:variable>
                <xsl:variable name="created_date" select="substring-before($created, ' ')"/>
                <xsl:variable name="year" select="substring($created_date, string-length($created_date) -3)"/>
                <xsl:variable name="day" select="substring-before($created_date, '/')"/>
                <xsl:variable name="month" select="format-number(substring-before(substring-after($created_date, $day), $year), '00')"/>
                <xsl:copy>
                    <xsl:apply-templates>
                        <xsl:sort select="$year" data-type="number"/>
                        <xsl:sort select="$month" data-type="number"/>
                        <xsl:sort select="$day" data-type="number"/>
                    </xsl:apply-templates>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

我得到的输出:

<?xml version="1.0" encoding="UTF-8"?>
<TestMessage>
    <INSTest>
        <INSClaim Id="1-TEST">
            <Id>1-TEST</Id>
            <INSTestElements>
                <INSTestElement>
                    <SortingOrder>2</SortingOrder>
                    <Created>12/29/2012 13:45:58</Created>
                    <Id>1-Element1</Id>
                </INSTestElement>
                <INSTestElement>
                    <SortingOrder>3</SortingOrder>
                    <Created>12/31/2012 14:45:58</Created>
                    <Id>1-Element2</Id>
                </INSTestElement>
                <INSTestElement>
                    <SortingOrder>1</SortingOrder>
                    <Created>12/31/2011 21:45:58</Created>
                    <Id>1-Element3</Id>
                </INSTestElement>
            </INSTestElements>
        </INSClaim>
    </INSTest>
</TestMessage>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<TestMessage>
    <INSTest>
        <INSClaim Id="1-TEST">
            <Id>1-TEST</Id>
            <INSTestElements>
                <INSTestElement>
                    <SortingOrder>1</SortingOrder>
                    <Created>12/31/2011 21:45:58</Created>
                    <Id>1-Element3</Id>
                </INSTestElement>
                <INSTestElement>
                    <SortingOrder>2</SortingOrder>
                    <Created>12/29/2012 13:45:58</Created>
                    <Id>1-Element1</Id>
                </INSTestElement>
                <INSTestElement>
                    <SortingOrder>3</SortingOrder>
                    <Created>12/31/2012 14:45:58</Created>
                    <Id>1-Element2</Id>
                </INSTestElement>
            </INSTestElements>
        </INSClaim>
    </INSTest>
</TestMessage>

我想我正在做的错误是,我试图应用于sort的子元素INSTestElement,因为我必须将其应用于INSTestElement自身。我尝试改组我开发的代码中的块,但没有任何成果。相反,我发现错误说invalid element variable under apply-templates

我主要关心的是如何提取created我必须用于对其父级进行排序的日期值INSTestElement..

4

2 回答 2

1

改变

        <xsl:for-each select="INSTestElement">
            <xsl:variable name="created"><xsl:value-of select="Created"/></xsl:variable>
            <xsl:variable name="created_date" select="substring-before($created, ' ')"/>
            <xsl:variable name="year" select="substring($created_date, string-length($created_date) -3)"/>
            <xsl:variable name="day" select="substring-before($created_date, '/')"/>
            <xsl:variable name="month" select="format-number(substring-before(substring-after($created_date, $day), $year), '00')"/>
            <xsl:copy>
                <xsl:apply-templates>
                    <xsl:sort select="$year" data-type="number"/>
                    <xsl:sort select="$month" data-type="number"/>
                    <xsl:sort select="$day" data-type="number"/>
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:for-each>

<xsl:apply-templates select="INSTestElement">
  <xsl:sort select="substring(substring-after(substring-after(Created, '/'), '/'), 1, 4)" data-type="number"/>
  <xsl:sort select="substring(Created, 1, 2)" data-type="number"/>
  <xsl:sort select="substring-before(substring-after(Created, '/'), '/')" data-type="number"/>
</xsl:apply-templates>

未经测试,但应该显示使用方法(即,将模板应用于这些INSTestElement元素并在执行此操作时进行排序)。表达式可能需要一些调整,xsl:sort select但您知道输入中日期的格式,这主要是选择正确部分的问题。

于 2013-06-04T10:55:54.403 回答
0

感谢 Martin 的精彩提示。将模板INSTestElements代码替换为以下代码。现在它根据字段的日期时间值Created升序排序。

<xsl:template match="INSTestElements">
    <xsl:copy>
        <xsl:apply-templates select="INSTestElement">
            <xsl:sort select="substring(substring-after(substring-after(Created, '/'), '/'), 1, 4)" data-type="number"/>
            <xsl:sort select="substring(Created, 1, 2)" data-type="number"/>
            <xsl:sort select="substring-before(substring-after(Created, '/'), '/')" data-type="number"/>
            <xsl:sort select="substring-before(substring-after(Created, ' '), ':')"/>
            <xsl:sort select="substring-before(substring-after(Created, ':'), ':')"/>
            <xsl:sort select="substring-after(substring-after(Created, ':'), ':')"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>
于 2013-06-04T11:30:45.450 回答