值如何绑定到Node然后获取该Node内的TEXT

时间:2014-06-13 09:50:33

标签: xml xslt

这次我有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]   |             |             |             |

1 个答案:

答案 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>

编辑2:

关于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>

我不知道其他两个描述需要做什么(如果有的话)。实施上述两项更改后获得的结果与您的(最新)预期结果相符。