3

我正在尝试使用 XSLT 将 XML 转换为 XML。输出 XML 应根据输入 XML 中的 ModificationTime 元素进行排序。下面是xml代码。

<?xml version="1.0" encoding="UTF-8"?>
<Process>
<currentDayAndHour>@Fri16</currentDayAndHour>

<!-- Few elements here. Need to retain them -->


<rowCount>1</rowCount>
<currentRow>1</currentRow>


<ClientList>
 <Status>0</Status>
 <ServerResponse>
  <Code>0</Code>
  <Text>OK</Text>
</ServerResponse>
<ServiceStartTime>2012-11-09 16:06:42.786</ServiceStartTime>
<ServiceEndTime>2012-11-09 16:06:42.827</ServiceEndTime>
<Files>
  <File>
    <Name>test.20121107215230411.txt</Name>
    <Size>29</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352343152</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>test.20121107183757513.txt</Name>
    <Size>29</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352331478</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>test1.20121107215230500.txt</Name>
    <Size>32</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352343152</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>test1.txt</Name>
    <Size>32</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352323788</ModificationTime>
    <Owner>65174</Owner>
    <Group>75431</Group>
  </File>
  <File>
    <Name>HMP_test.txt</Name>
    <Size>28</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352199478</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>test1.20121107183757585.txt</Name>
    <Size>32</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352331478</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>client_access.20121108101411179.txt</Name>
    <Size>4182</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352387653</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>TechMtngAgenda.txt</Name>
    <Size>107</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1352044842</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
  <File>
    <Name>test.txt</Name>
    <Size>29</Size>
    <Type>Regular</Type>
    <Permissions>-rw-r--r--</Permissions>
    <ModificationTime>1350063313</ModificationTime>
    <Owner>19737</Owner>
    <Group>70902</Group>
  </File>
</Files>
</ClientList>
<currentDocument>1</currentDocument>
</Process>

我需要包含所有输入元素的输出 XML,但 Files 标记应按 ModificationTime 的递增顺序包含每个文件。我对 XSLT 有点陌生。我尝试使用 xsl:sort 但无法获得所需的结果。

4

1 回答 1

1

此样式表将在 XSLT 1.0 中执行您想要的操作

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

  <!-- Identity template -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Files">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="File">
        <xsl:sort order="ascending" data-type="number" select="ModificationTime"/>
      </xsl:apply-templates>      
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

此样式表将在 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">

  <!-- Identity template -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Files">
    <xsl:copy>
      <xsl:sequence select="@*"/>
      <xsl:perform-sort select="File">
        <xsl:sort order="ascending" select="xs:integer(ModificationTime)"/>
      </xsl:perform-sort>      
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

在这两种情况下,Identity 模板都用于准确复制文档,并xsl:template引入了一个单一的模板来覆盖Files元素的处理。在 XSLT 1.0 示例xsl:apply-templates中,使用 withxsl:sortFile元素进行排序ModificationTime<xsl:apply-templates select="File">对已排序元素的处理将传递File回 Identity 模板,因此它可能会被进一步覆盖。

在 XSLT 2.0 示例xsl:sequence中,用于将输入节点直接插入到结果树中。同样xsl:perform-sort直接返回排序后的序列,而不是执行额外的指令来复制元素。请注意,这些更改可能会使样式表的执行速度更快,但也会降低未来维护的灵活性。当您直接选择事物时,添加覆盖要困难得多。XSLT 1.0 样式表或其处理方式可以在 XSLT 2.0 中完成,而无需进行重大更改。最后一点,这两个例子都省略了不是元素node()的任何子元素。要捕获那些您可以在 XSLT 1.0 中添加的内容FilesFile

<xsl:apply-templates select="node()[not(self::File)]"/>

或者仅在 XSLT 2.0 中

<xsl:apply-templates select="node() except File"/>

或者

<xsl:sequence select="node() except File"/>
于 2012-11-13T16:43:14.973 回答