<?xml version="1.0" encoding="UTF-8"?>
<accountList>
<previousAccount>
<account>
<name>NASH</name>
<accountStatus>REMOVED</accountStatus>
<accNo>1</accNo>
</account>
<account>
<name>ADOGA</name>
<accountStatus>REMOVED</accountStatus>
<accNo>8</accNo>
</account>
<account>
<name>LUCAS</name>
<accountStatus>HOLD</accountStatus>
<accNo>09</accNo>
</account>
<account>
<name>DONALD</name>
<accountStatus>HOLD</accountStatus>
<accNo>21</accNo>
</account>
<account>
<Title>Miss</Title>
<firstName>HILARI</firstName>
<lastName>WOOD</lastName>
<city>LONDON</city>
<accNo>24</accNo>
</account>
</previousAccount>
<account>
<Title>Mr</Title>
<firstName>RICHARD</firstName>
<lastName>JOHN</lastName>
<city>london</city>
<accNo>02</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>xxx</firstName>
<lastName>JOHN</lastName>
<city>London</city>
<accNo>17</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>HEWIT</firstName>
<lastName>JOHN</lastName>
<city>LONDON</city>
<accNo>20</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>xxx</firstName>
<lastName>JOHN</lastName>
<city>LONDON</city>
<accNo>21</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>KEVIN</firstName>
<lastName>PETE</lastName>
<city>LONDON</city>
<accNo>07</accNo>
</account>
</accountList>
xslt代码
<xsl:stylesheet version="2.0"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform file:/C:/Users/n434947/Desktop/workspace/SonicXSLT/BA xslt page.xsd"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="text"/>
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="accountList">
<xsl:for-each-group select="descendant::account" group-starting-with="*[firstName != 'xxx' or lastName != preceding-sibling::*[1]/lastName]">
<xsl:sort select="accNo" order="ascending"/>
<xsl:if test="previousAccount/account/accountStatus='REMOVED'">
<xsl:value-of select="previousAccount/account[accountStatus='REMOVED']/accNo"/>
</xsl:if>
<xsl:value-of select="previousAccount/account[accountStatus='HOLD']/accNo"/>
<xsl:value-of select="accNo"/>
<xsl:text> </xsl:text>
<xsl:value-of select="lastName"/>
<xsl:text> </xsl:text>
<xsl:value-of select="firstName"/>
<xsl:value-of select="$newline"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
根据我的要求,我必须对两个不同的X路径(如下面的
)进行排序accountList/previousAccount/account/accNo
accountList/account/accNo
我使用了后代,这对我的要求不起作用。请帮我解决这个问题。
实际输出
02 JOHN RICHARD
07 PETE KEVIN
1
20 JOHN HEWIT
24 WOOD HILARI
期待输出
01 REMOVED NASH
02 JOHN RICHARD
07 PETE KEVIN
08 REMOVED ADOGA
09 HOLD LUCAS
20 JOHN HEWIT
24 HOLD DONALD
答案 0 :(得分:0)
在我的要求中,我得对它们进行排序,这些都来自两个 不同的X路径如下
accountList/previousAccount/account/accNo accountList/account/accNo
也许你可以在没有两个不同XPath的地方做到这一点。如果你减少了上面的XPath,删除previousAccount
就会发现它们基本相同。您只需要搜索accountList
...
accountList//account/accNo
如果您使用xsl:for-each
或xsl:apply-templates
执行此操作,您的排序会变得更加轻松。任何其他过滤,例如firstName != 'xxx'
都可以添加到谓词中。
我认为这是你最初尝试的内容,但却因xsl:for-each-group
而崩溃了。
这是一个例子(also seen here)。我完全猜测输出的实际格式;特别是田野的填充物。我可能过度复杂了,但它至少应该是一个开始。
XML输入
<accountList>
<previousAccount>
<account>
<name>NASH</name>
<accountStatus>REMOVED</accountStatus>
<accNo>1</accNo>
</account>
<account>
<name>ADOGA</name>
<accountStatus>REMOVED</accountStatus>
<accNo>8</accNo>
</account>
<account>
<name>LUCAS</name>
<accountStatus>HOLD</accountStatus>
<accNo>09</accNo>
</account>
<account>
<name>DONALD</name>
<accountStatus>HOLD</accountStatus>
<accNo>21</accNo>
</account>
<account>
<Title>Miss</Title>
<firstName>HILARI</firstName>
<lastName>WOOD</lastName>
<city>LONDON</city>
<accNo>24</accNo>
</account>
</previousAccount>
<account>
<Title>Mr</Title>
<firstName>RICHARD</firstName>
<lastName>JOHN</lastName>
<city>london</city>
<accNo>02</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>xxx</firstName>
<lastName>JOHN</lastName>
<city>London</city>
<accNo>17</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>HEWIT</firstName>
<lastName>JOHN</lastName>
<city>LONDON</city>
<accNo>20</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>xxx</firstName>
<lastName>JOHN</lastName>
<city>LONDON</city>
<accNo>21</accNo>
</account>
<account>
<Title>Mr</Title>
<firstName>KEVIN</firstName>
<lastName>PETE</lastName>
<city>LONDON</city>
<accNo>07</accNo>
</account>
</accountList>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:l="local" xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:function name="l:pad">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="length" as="xs:integer"/>
<xsl:sequence select="l:pad($input,$length,'right')"/>
</xsl:function>
<xsl:function name="l:pad">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="length" as="xs:integer"/>
<xsl:param name="align" as="xs:string"/>
<xsl:variable name="inputLength" select="string-length($input)"/>
<xsl:variable name="padding" select="if ($length > $inputLength) then
for $x in 1 to ($length - $inputLength) return ' ' else ''"/>
<xsl:sequence select="if ($align = 'right') then
string-join(($padding,$input),'') else
string-join(($input,$padding),'')"/>
</xsl:function>
<xsl:template match="/*">
<xsl:for-each select=".//account[not(firstName = 'xxx')]">
<xsl:sort select="accNo" data-type="number"/>
<xsl:if test="not(position()=1)"><xsl:text>
</xsl:text></xsl:if>
<xsl:value-of select="l:pad(
l:pad(format-number(accNo,'00'),5),6,'left')"/>
<xsl:value-of select="l:pad(
concat(accountStatus,' '),10,'left')"/>
<xsl:value-of select="l:pad(
string-join((lastName,name|firstName),' '),20,'left')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出(这对我来说并不明显为什么&#34; WOOD HILARI&#34;应该被排除在外)
01 REMOVED NASH
02 JOHN RICHARD
07 PETE KEVIN
08 REMOVED ADOGA
09 HOLD LUCAS
20 JOHN HEWIT
21 HOLD DONALD
24 WOOD HILARI