这次我有XML和XSLT,我希望XSLT自动从同一XML文件中的另一个节点获取值。
XML:
<DATA>
<CountryList>
<CountryName code="AA" name="Antarctica" IsT="True"/>
<CountryName code="AB" name="Abkhazia" IsT="False"/>
</CountryList>
<Description1List>
<Description1Name Description1Id="1" RecordType="Person">P1</Description1Name>
<Description1Name Description1Id="2" RecordType="Person">P2</Description1Name>
<Description1Name Description1Id="3" RecordType="Entity">E1</Description1Name>
</Description1List>
<Description2List>
<Description2Name Description2Id="1" Description1Id="2">P21</Description2Name>
<Description2Name Description2Id="2" Description1Id="2">P22</Description2Name>
<Description2Name Description2Id="3" Description1Id="3">E11</Description2Name>
</Description2List>
<Description3List>
<Description3Name Description3Id="1" Description2Id="1">P211</Description3Name>
<Description3Name Description3Id="2" Description2Id="3">E111</Description3Name>
</Description3List>
<DateTypeList>
<DateType RecordType="Person" Id="1" name="Date of A"/>
<DateType RecordType="Person" Id="2" name="Date of B"/>
<DateType RecordType="Entity" Id="3" name="Date of C"/>
</DateTypeList>
<Records>
<Person id="752" date="15-Oct-2013">
<Country CountryType="BB">
<CountryValue>AA</CountryValue>
</Country>
<Descriptions>
<Description Description1="1" Description2="2" Description3="1"/>
<Description Description1="2"/>
</Descriptions>
</Person>
<Entity id="758" date="15-Oct-2013">
<Country CountryType="BC">
<CountryValue>AB</CountryValue>
</Country>
<Descriptions>
<Description Description1="3" Description2="3" Description3="2"/>
<Description Description1="3"/>
</Descriptions>
</Entity>
</Records>
</DATA>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>Date</th>
<th>Country</th>
<th>Description1</th>
<th>Description2</th>
<th>Description3</th>
</tr>
<xsl:for-each select="DATA/Records/Person">
<xsl:variable name="varPerson" select="."/>
<xsl:for-each select="$varPerson/Country">
<xsl:variable name="varCountry" select="."/>
<xsl:for-each select="$varPerson/Descriptions/Description|$varPerson[not ($varPerson/Descriptions/Description)]">
<xsl:variable name="varDescription" select="."/>
<tr>
<td>
<xsl:value-of select="normalize-space($varPerson/@id)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varPerson/@date)"/>
</td>
<td>
[<xsl:value-of select="normalize-space($varCountry/@CountryType)"/>]
<xsl:value-of select="normalize-space($varCountry/CountryValue)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varDescription/@Description1)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varDescription/@Description2)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varDescription/@Description3)"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
<!-- -->
<xsl:for-each select="DATA/Records/Entity">
<xsl:variable name="varEntity" select="."/>
<xsl:for-each select="$varEntity/Country">
<xsl:variable name="varCountry" select="."/>
<xsl:for-each select="$varEntity/Descriptions/Description|$varEntity[not ($varEntity/Descriptions/Description)]">
<xsl:variable name="varDescription" select="."/>
<tr>
<td>
<xsl:value-of select="normalize-space($varEntity/@id)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varEntity/@date)"/>
</td>
<td>
[<xsl:value-of select="normalize-space($varCountry/@CountryType)"/>]
<xsl:value-of select="normalize-space($varCountry/CountryValue)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varDescription/@Description1)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varDescription/@Description2)"/>
</td>
<td>
<xsl:value-of select="normalize-space($varDescription/@Description3)"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
我的结果是
|ID |Date |Country |Description1 |Description2 |Description3 |
|752 |15-Oct-2013 |[BB] AA |1 |2 |1 |
|752 |15-Oct-2013 |[BB] AA |2 | | |
|758 |15-Oct-2013 |[BC] AB |3 |3 |2 |
|758 |15-Oct-2013 |[BC] AB |3 | | |
我期望的结果是什么
|ID |Date |Country |Description1 |Description2 |Description3 |
|752 |15-Oct-2013 |[BB] Antarctica [True] |P1 |P22 |P211 |
|752 |15-Oct-2013 |[BB] Antarctica [True] |P2 | | |
|758 |15-Oct-2013 |[BC] Abkhazia [False] |E1 |E11 |E111 |
|758 |15-Oct-2013 |[BC] Abkhazia [False] |E1 | | |
对于国家值AA | AB应该绑定到DATA \ CountryList,描述{N}也应该相应地绑定到描述{N}列表。
**请注意,Entity节点不应该绑定到任何&#34; RecordType =&#34; Person&#34;&#34;在Description1List ...
中谢谢
EDIT1 XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="country-by-code" match="CountryName" use="@code"/>
<xsl:key name="Description1-by-code" match="Description1Name" use="@Description1Id"/>
<xsl:key name="Description2-by-code" match="Description2Name" use="@Description2Id"/>
<xsl:key name="Description3-by-code" match="Description3Name" use="@Description3Id"/>
<xsl:template match="/">
<html>
<body>n
<table border="1">
<tr>
<th>ID</th>
<th>Date</th>
<th>Country</th>
<th>Description1</th>
<th>Description2</th>
<th>Description3</th>
</tr>
<xsl:for-each select="DATA/Records/Person">
<xsl:variable name="varPerson" select="."/>
<xsl:for-each select="$varPerson/Country">
<xsl:variable name="varCountry" select="."/>
<xsl:for-each select="$varPerson/Descriptions/Description|$varPerson[not ($varPerson/Descriptions/Description)]">
<xsl:variable name="varDescription" select="."/>
<tr>
<td>
<xsl:value-of select="$varPerson/@id"/>
</td>
<td>
<xsl:value-of select="$varPerson/@date"/>
</td>
<td>
[<xsl:value-of select="$varCountry/@CountryType"/>]
<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@name"/>
[<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@IsT"/>]
</td>
<td>
<xsl:value-of select="key('Description1-by-code', $varDescription/@Description1)"/>
</td>
<td>
<xsl:value-of select="key('Description2-by-code', $varDescription/@Description2)"/>
</td>
<td>
<xsl:value-of select="key('Description3-by-code', $varDescription/@Description3)"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
<!-- -->
<xsl:for-each select="DATA/Records/Entity">
<xsl:variable name="varEntity" select="."/>
<xsl:for-each select="$varEntity/Country">
<xsl:variable name="varCountry" select="."/>
<xsl:for-each select="$varEntity/Descriptions/Description|$varEntity[not ($varEntity/Descriptions/Description)]">
<xsl:variable name="varDescription" select="."/>
<tr>
<td>
<xsl:value-of select="$varEntity/@id"/>
</td>
<td>
<xsl:value-of select="$varEntity/@date"/>
</td>
<td>
[<xsl:value-of select="$varCountry/@CountryType"/>]
<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@name"/>
[<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@IsT"/>]
</td>
<td>
<xsl:value-of select="key('Description1-by-code', $varDescription/@Description1)"/>
</td>
<td>
<xsl:value-of select="key('Description2-by-code', $varDescription/@Description2)"/>
</td>
<td>
<xsl:value-of select="key('Description3-by-code', $varDescription/@Description3)"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XML DATA2
<DATA>
<CountryList>
<CountryName code="AA" name="Antarctica" IsT="True"/>
<CountryName code="AB" name="Abkhazia" IsT="False"/>
</CountryList>
<Description1List>
<Description1Name Description1Id="1" RecordType="Person">P1</Description1Name>
<Description1Name Description1Id="2" RecordType="Person">P2</Description1Name>
<Description1Name Description1Id="1" RecordType="Entity">E1</Description1Name>
</Description1List>
<Description2List>
<Description2Name Description2Id="1" Description1Id="2">P21</Description2Name>
<Description2Name Description2Id="2" Description1Id="2">P22</Description2Name>
<Description2Name Description2Id="3" Description1Id="3">E11</Description2Name>
</Description2List>
<Description3List>
<Description3Name Description3Id="1" Description2Id="1">P211</Description3Name>
<Description3Name Description3Id="2" Description2Id="3">E111</Description3Name>
</Description3List>
<DateTypeList>
<DateType RecordType="Person" Id="1" name="Date of A"/>
<DateType RecordType="Person" Id="2" name="Date of B"/>
<DateType RecordType="Entity" Id="3" name="Date of C"/>
</DateTypeList>
<Records>
<Person id="752" date="15-Oct-2013">
<Country CountryType="BB">
<CountryValue>AA</CountryValue>
</Country>
<Descriptions>
<Description Description1="1" Description2="2" Description3="1"/>
<Description Description1="2"/>
</Descriptions>
</Person>
<Entity id="758" date="15-Oct-2013">
<Country CountryType="BC">
<CountryValue>AB</CountryValue>
</Country>
<Descriptions>
<Description Description1="1" Description2="3" Description3="2"/>
<Description Description1="3"/>
</Descriptions>
</Entity>
</Records>
</DATA>
我期望的结果是什么
|ID |Date |Country |Description1 |Description2 |Description3 |
|752 |15-Oct-2013 |[BB] Antarctica [True] |P1 |P22 |P211 |
|752 |15-Oct-2013 |[BB] Antarctica [True] |P2 | | |
|758 |15-Oct-2013 |[BC] Abkhazia [False] |E1 |E11 |E111 |
|758 |15-Oct-2013 |[BC] Abkhazia [False] | | | |
实际结果是
|ID |Date |Country |Description1 |Description2 |Description3 |
|752 |15-Oct-2013 |[BB] Antarctica [True] |P1 |P22 |P211 |
|752 |15-Oct-2013 |[BB] Antarctica [True] |P2 | | |
|758 |15-Oct-2013 |[BC] Abkhazia [False] |P1 |E11 |E111 |
|758 |15-Oct-2013 |[BC] Abkhazia [False] | | | |
答案 0 :(得分:1)
将此定义添加到样式表的顶部(在任何模板之外):
<xsl:key name="country-by-code" match="CountryName" use="@code" />
然后,而不是:
<td>
[<xsl:value-of select="normalize-space($varCountry/@CountryType)"/>]
<xsl:value-of select="normalize-space($varCountry/CountryValue)"/>
</td>
使用:
<td>
[<xsl:value-of select="$varCountry/@CountryType"/>]
<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@name"/>
[<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@IsT"/>]
</td>
P.S。我不明白为什么你需要所有那些normalize-space()。
关于你的其他问题,我建议你稍微简化你的结构 - 很多事情会变得更容易:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="country-by-code" match="CountryName" use="@code"/>
<xsl:key name="Description1-by-id" match="Description1Name" use="@Description1Id"/>
<xsl:key name="Description2-by-id" match="Description2Name" use="@Description2Id"/>
<xsl:key name="Description3-by-id" match="Description3Name" use="@Description3Id"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>Date</th>
<th>Country</th>
<th>Description1</th>
<th>Description2</th>
<th>Description3</th>
</tr>
<xsl:apply-templates select="DATA/Records/*"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Person | Entity">
<xsl:variable name="varRrecord" select="."/>
<xsl:for-each select="$varRrecord/Country">
<xsl:variable name="varCountry" select="."/>
<xsl:for-each select="$varRrecord/Descriptions/Description | $varRrecord[not(Descriptions/Description)]">
<xsl:variable name="varDescription" select="."/>
<tr>
<td><xsl:value-of select="$varRrecord/@id"/></td>
<td><xsl:value-of select="$varRrecord/@date"/></td>
<td>
[<xsl:value-of select="$varCountry/@CountryType"/>]
<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@name"/>
[<xsl:value-of select="key('country-by-code', $varCountry/CountryValue)/@IsT"/>]
</td>
<td><xsl:value-of select="key('Description1-by-id', $varDescription/@Description1)"/></td>
<td><xsl:value-of select="key('Description2-by-id', $varDescription/@Description2)"/></td>
<td><xsl:value-of select="key('Description3-by-id', $varDescription/@Description3)"/></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
关于Description1,我建议你改变这个:
<xsl:key name="Description1-by-id" match="Description1Name" use="@Description1Id"/>
为:
<xsl:key name="Description1" match="Description1Name" use="concat(@Description1Id, '|', @RecordType)"/>
和此:
<td><xsl:value-of select="key('Description1-by-id', $varDescription/@Description1)"/></td>
为:
<td><xsl:value-of select="key('Description1', concat($varDescription/@Description1, '|', name($varRrecord)))"/></td>
我不知道其他两个描述需要做什么(如果有的话)。实施上述两项更改后获得的结果与您的(最新)预期结果相符。