xsl:key如何选择不匹配的键值

时间:2016-04-04 12:23:16

标签: xslt xslt-2.0

我正在尝试使用xsl:key比较两个xml,但不确定如何打印不匹配的键。在这种情况下,我键入b.xml并与a.xml进行比较,但它不会从b.xml打印不匹配的键。

A.XML

<root>
<metas>
    <meta>
        <name>x</name>
        <value>0</value>
    </meta>
    <meta>
        <name>y</name>
        <value>1</value>
    </meta>
    <meta>
        <name>z</name>
        <value>1</value>
    </meta>
</metas>

B.XML

<root>
<metas>
    <info>
        <name>a</name>
        <value>0</value>
    </info>
    <info>
        <name>y</name>
        <value>1</value>
    </info>
    <info>
        <name>z</name>
        <value>1</value>
    </info>
</metas>

期望的输出:

    Table

                a.xml               b.xml
    name        missing in a.xml    a
    value       missing in a.xml    0

    name        x                   missing in b.xml
    value       0                   missing in b.xml

    name        y                   y
    value       1                   1

    name        z                   z
    value       1                   1

我的xsl;

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:param name="uri" as="xs:string" select="'b.xml'"/>
<xsl:param name="b" as="document-node()" select="doc($uri)"/>
<xsl:key name="bCompare" match="root/metas/info" use="name"/>
<xsl:template match="/">
    <html>
        <head>
            <title>Test</title>
        </head>
        <body>
            <table>
                <tr>
                    <td></td>
                    <th>a.xml</th>
                    <th>b.xml</th>
                </tr>
            <xsl:apply-templates/>                    
            </table>
        </body>
    </html>
</xsl:template>
<xsl:template match="metas">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="meta">        
    <xsl:variable name="compare" select="key('bCompare', name, $b)"/>
    <tr>
        <th>Name</th>
        <td>
            <xsl:value-of select="name"/>             
        </td>
        <td>
            <xsl:value-of select="$compare/name"/>
            <xsl:if test="empty($compare/name)">missing in b.xml</xsl:if>
        </td>
    </tr>
    <tr>
        <th>Value</th>
        <td>
            <xsl:value-of select="value"/>
        </td>
        <td>
            <xsl:value-of select="$compare/value"/>
            <xsl:if test="empty($compare/value)">missing in b.xml</xsl:if>
        </td>
    </tr>
</xsl:template>

1 个答案:

答案 0 :(得分:2)

您还需要为其他方向定义一个键,即<xsl:key name="aCompare" match="root/metas/meta" use="name"/>,然后您需要确保使用例如{2}处理第二个文档的那些元素。 <xsl:apply-templates/><xsl:variable name="main-doc" select="/"/><xsl:apply-templates select="$b//info/meta[not(name = key('bCompare', $main-doc//meta/name, $main-doc))]"/>然后你需要一个模板

<xsl:template match="info">        
    <xsl:variable name="compare" select="key('aCompare', name, $main-doc)"/>
    <tr>
        <th>Name</th>
        <td>
            <xsl:value-of select="$compare/name"/>
            <xsl:if test="empty($compare/name)">missing in a.xml</xsl:if>
        </td>
        <td>
            <xsl:value-of select="name"/>             
        </td>
    </tr>
    <tr>
        <th>Value</th>
        <td>
            <xsl:value-of select="$compare/value"/>
            <xsl:if test="empty($compare/value)">missing in a.xml</xsl:if>
        </td>
        <td>
            <xsl:value-of select="value"/>
        </td>
    </tr>
</xsl:template>