我是新的xslt轉換,我遇到了一些麻煩。 我需要排序和過濾元素,在下面的例子中,我設法用兩個xlt轉換對輸入xml進行排序和過濾。 我的問題是:如何對一個xsl文件進行排序然後過濾排序後的數據? 在此先感謝。xslt在排序後的數據上應用模板
XML輸入:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<data>
<id>00000_1111_2222</id>
<startedAt>2017-08-21T11:55:08.382Z</startedAt>
<endedAt>2017-08-21T12:07:08.539Z</endedAt>
<positions>
<timestamp>2017-08-21T11:55:28.041Z</timestamp>
<latitude>40.2407009</latitude>
<longitude>10.7750499</longitude>
</positions>
<positions>
<timestamp>2017-08-21T11:55:28.041Z</timestamp>
<latitude>40.2409364</latitude>
<longitude>10.7748426</longitude>
</positions>
<positions>
<timestamp>2017-08-21T11:55:38.041Z</timestamp>
<latitude>40.240409</latitude>
<longitude>10.7751432</longitude>
</positions>
</data>
</root>
XSL排序:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="*[not(self::positions)]"/>
<xsl:apply-templates select="positions">
<xsl:sort select="timestamp" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSL濾波:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="*[not(self::positions)]" />
<xsl:copy-of select="positions[position() <= 4]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果我想保留原始的XMLStructure,是corret這個XSL?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Sort and filter positions elements -->
<xsl:template match="data">
<xsl:copy>
<xsl:for-each select="positions">
<xsl:sort select="timestamp" order="descending"/>
<xsl:if test="position() <= 2">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我的預期輸出XML是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<data>
<id>00000_1111_2222</id>
<startedAt>2017-08-21T11:55:08.382Z</startedAt>
<endedAt>2017-08-21T12:07:08.539Z</endedAt>
<positions>
<timestamp>2017-08-21T11:55:38.041Z</timestamp>
<latitude>40.240409</latitude>
<longitude>10.7751432</longitude>
</positions>
<positions>
<timestamp>2017-08-21T11:55:28.041Z</timestamp>
<latitude>40.2407009</latitude>
<longitude>10.7750499</longitude>
</positions>
</data>
</root>
但這種方式我失去所有的元素沒有 「位置」 元素的子:ID ,開始了,結束了。 因此,我試圖在<xsl:template match="data">
之後加上:<xsl:apply-templates select="*
[not(self :: positions)] />,但是如果所有的NOT「position」child都在position元素後面呢? XML結構/訂單。有沒有辦法來實現一種通用的方式最後這件事? 謝謝。
謝謝你侑很好的答案,只是一件事:如果我會保留原始的XML文件結構?如何保護其他節點?我將舉一個編輯示例 – Daniel
好吧,您的原始方法以及您的評論有一個方法,即在要處理其他子節點的位置添加一個「apply-templates」。至於更通用的解決方案,我認爲如果您提出一個顯示某些輸入樣本的新問題會更好,我認爲我們需要了解輸入可以存在哪些變體(「位置」之前和/或之後的內容,與內容混合的內容'職位'),然後你如何重新排列元素(所有'位置'一起?)。還請明確說明您是否可以使用XSLT 2.0。 –