2012-11-13 144 views
3

我試圖使用XSLT將XML轉換爲XML。輸出XML應該根據輸入XML中的ModificationTime元素進行排序。 以下是xml代碼。使用XSLT進行排序後將XML轉換爲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與所有輸入元素,但文件標記應該包含每個文件以增加的順序ModificationTime。我對XSLT很陌生。我嘗試使用xsl:sort,但無法獲得所需的結果。

回答

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> 

在這兩種情況下,身份模板用於將文件複製正好和單個xsl:template被引入來覆蓋對Files元素的處理。在XSLT 1.0示例中,xsl:apply-templatesxsl:sort一起使用來將File元素排序爲ModificationTime。對排序的File元素的處理<xsl:apply-templates select="File">被傳回到身份模板,因此可能會被進一步覆蓋。

在XSLT 2.0示例中,xsl:sequence用於將輸入節點直接插入結果樹。同樣,xsl:perform-sort直接返回排序的序列,而不是執行其他指令來複制元素。請注意,這些更改可能會使樣式表執行更快,但也會降低未來維護的靈活性。當您直接選擇東西時,添加覆蓋項會更加困難。 XSLT 1.0樣式表或它的處理樣式可以在XSLT 2.0中完成,而無需進行重大更改。最後一點,這兩個例子都省略了Files的任何node()子元素,它不是File元素。捕捉那些你可以在XSLT 1.0中添加

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

或者在XSLT 2.0只

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

<xsl:sequence select="node() except File"/> 
+0

的'except'運營商僅在XPath 2.0中可用 - 這是,在XSLT 2.0中。請改正。 –

+0

感謝您的支持。 – nine9ths

+0

另外,它會更好(更可讀和更高效):'not(self :: File)'而不是'not(name()='File')' –