XSLT匹配2个元素以获得另一个元素

时间:2013-05-07 06:56:49

标签: xslt xslt-1.0

我对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>

我要做的是匹配节点//帐户/帐户/ Id与// InvestmentHoldingBalances / HoldingBalance / AccountId,当有匹配时,获取属于该帐户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">&#10;</xsl:text> 
</xsl:template>

</xsl:stylesheet>

输出与每行的所有者ID相同(即最后一列为'273228M'),而不是根据帐户ID匹配的匹配所有者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"

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

基本问题在

<xsl:value-of select="../../Accounts/Account/Owners/Owner/Id"/>

select表达式选择整个文档中的所有所有者ID,无论帐户ID如何,当您要求value-of一组多个节点时,结果由规范是文档顺序中集合中第一个节点的值。

您需要以某种方式将设置约束为匹配的帐户,最简单的方法是

<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"/>

无论哪种方式,您实际上并不需要if周围的value-of,因为在没有帐户与当前AccountId匹配的情况下,您会要求value-of 1}}一个空节点集,根据定义是空字符串。

最后,当您使用disable-output-escaping时,您永远不需要<xsl:output method="text"/> - 只需<xsl:text>&#10;</xsl:text>就可以在这里工作。