我对XSLT比较陌生,但我想在元素之间执行我认为相对简单的匹配以获得另一个。
下面是XML的一个片段。版本= 1.0,输出为文本(将xml转换为文本)。
<Accounts>
<Account>
<Id>273228MD301</Id>
<EPIProductCode>IPP4D3</EPIProductCode>
<Name>Mr John Smith</Name>
<Status>Open</Status>
<Owners>
<Owner>
<Id>273228M</Id>
</Owner>
</Owners>
<Advisers>
<Adviser>
<Id>286666</Id>
<PrimaryAdviser>true</PrimaryAdviser>
</Adviser>
</Advisers>
<Delete>false</Delete>
<LastModified>2012-06-08T15:19:19</LastModified>
</Account>
<Account>
<Id>273228MD399</Id>
<EPIProductCode>IPAAA</EPIProductCode>
<Name>Sir Leslie Patterson</Name>
<Status>Open</Status>
<Owners>
<Owner>
<Id>2732299</Id>
</Owner>
</Owners>
<Advisers>
<Adviser>
<Id>286666</Id>
<PrimaryAdviser>true</PrimaryAdviser>
</Adviser>
</Advisers>
<Delete>false</Delete>
<LastModified>2012-06-08T15:19:19</LastModified>
</Account>
<Account>
<Id>273228MD999</Id>
<EPIProductCode>IPYYY</EPIProductCode>
<Name>Dame Edna</Name>
<Status>Open</Status>
<Owners>
<Owner>
<Id>27322YY</Id>
</Owner>
</Owners>
<Advisers>
<Adviser>
<Id>286666</Id>
<PrimaryAdviser>true</PrimaryAdviser>
</Adviser>
</Advisers>
<Delete>false</Delete>
<LastModified>2012-06-08T15:19:19</LastModified>
</Account>
</Accounts>
<InvestmentHoldingBalances>
<HoldingBalance>
<AccountId>273228MD399</AccountId>
<InvestmentCode>TEST123</InvestmentCode>
<Exchange>FND</Exchange>
<UnitBalance>
<Settled Currency="AUD">0</Settled>
<Pending Currency="AUD">0</Pending>
<AsAtDate>2012-06-08T15:19:34</AsAtDate>
</UnitBalance>
<LastModified>2012-05-16T00:00:00</LastModified>
</HoldingBalance>
<HoldingBalance>
<AccountId>273228MD301</AccountId>
<InvestmentCode>0114AU</InvestmentCode>
<Exchange>FND</Exchange>
<UnitBalance>
<Settled Currency="AUD">0</Settled>
<Pending Currency="AUD">0</Pending>
<AsAtDate>2012-06-08T15:19:34</AsAtDate>
</UnitBalance>
<LastModified>2012-05-16T00:00:00</LastModified>
</HoldingBalance>
<HoldingBalance>
<AccountId>273228MD301</AccountId>
<InvestmentCode>0016AU</InvestmentCode>
<Exchange>FND</Exchange>
<UnitBalance>
<Settled Currency="AUD">0</Settled>
<Pending Currency="AUD">0</Pending>
<AsAtDate>2012-06-08T15:19:34</AsAtDate>
</UnitBalance>
<LastModified>2012-05-16T00:00:00</LastModified>
</HoldingBalance>
<HoldingBalance>
<AccountId>273228MD301</AccountId>
<InvestmentCode>0277AU</InvestmentCode>
<Exchange>FND</Exchange>
<UnitBalance>
<Settled Currency="AUD">0</Settled>
<Pending Currency="AUD">0</Pending>
<AsAtDate>2012-06-08T15:19:34</AsAtDate>
</UnitBalance>
<LastModified>2012-05-15T00:00:00</LastModified>
</HoldingBalance>
<HoldingBalance>
<AccountId>273228MD999</AccountId>
<InvestmentCode>TD0155</InvestmentCode>
<Exchange>FND</Exchange>
<UnitBalance>
<Settled Currency="AUD">0</Settled>
<Pending Currency="AUD">0</Pending>
<AsAtDate>2012-06-08T15:19:34</AsAtDate>
</UnitBalance>
<LastModified>2012-05-21T00:00:00</LastModified>
</HoldingBalance>
</InvestmentHoldingBalances>
我要做的是匹配节点//Accounts/Account/Id与//InvestmentHoldingBalances/HoldingBalance/AccountId,当有一个匹配得到对应的//Owners/Owner/Id属于该帐户Id。我得到的结果,当我做一个匹配是第一个//所有者/所有者/Id为所有行的不是个人匹配一个。这是我的xslt
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<!-- Create Header Record -->
<xsl:template match="xxxxxx">
<!-- Some other xslt here to extract header info -->
<xsl:apply-templates select="InvestmentHoldingBalances/HoldingBalance" />
</xsl:template>
<!-- Create HoldingBalance Records -->
<xsl:template match="HoldingBalance">
<xsl:value-of select="AccountId" />
<xsl:text>","</xsl:text>
<xsl:value-of select="InvestmentCode" />
<xsl:text>","</xsl:text>
<xsl:value-of select="Exchange" />
<xsl:text>","</xsl:text>
<xsl:if test="../../Accounts/Account/Id=AccountId">
<xsl:value-of select="../../Accounts/Account/Owners/Owner/Id" />
</xsl:if>
<xsl:text>"</xsl:text>
<xsl:text disable-output-escaping="yes"> </xsl:text>
</xsl:template>
</xsl:stylesheet>
输出为每行相同的Owner Id(即'273228M'为最后一列),而不是根据Account Id匹配的匹配Owner Id;
273228MD399","TEST123","FND","273228M"
273228MD301","0114AU","FND","273228M"
273228MD301","0016AU","FND","273228M"
273228MD301","0277AU","FND","273228M"
273228MD999","TD0155","FND","273228M"
我想要的结果是这样的;
273228MD399","TEST123","FND","2732299"
273228MD301","0114AU","FND","273228M"
273228MD301","0016AU","FND","273228M"
273228MD301","0277AU","FND","273228M"
273228MD999","TD0155","FND","27322YY"
谢谢你的建议
基本问题在
<xsl:value-of select="../../Accounts/Account/Owners/Owner/Id"/>
select表达式选择整个文档中的所有所有者id,而不管帐户id是什么,当您请求包含多个节点的value-of
a集时,规范将结果定义为文档顺序中集合中第一个节点的值。
您需要以某种方式将集合约束为仅匹配帐户,最简单的方法是
<xsl:value-of select="../../Accounts/Account[Id = current()/AccountId]/Owners/Owner/Id"/>
但是在样式表的顶层(直接放在xsl:output
元素之后)定义键可能会更有效
<xsl:key name="accountById" match="Account" use="Id"/>
然后可以使用
在value-of
中提取正确的帐户<xsl:value-of select="key('accountById', AccountId)/Owners/Owner/Id"/>
无论哪种方式,您实际上都不需要value-of
周围的if
,因为在没有帐户与当前AccountId
匹配的情况下,您将要求value-of
为空节点集,这是根据定义的空字符串。
最后,当你使用<xsl:output method="text"/>
时,你不应该需要disable-output-escaping
-简单的<xsl:text> </xsl:text>
在这里也可以工作。