Xslt 比较每个XML使用的多个XML

Xslt 比较每个XML使用的多个XML,xslt,xslt-1.0,xslt-2.0,Xslt,Xslt 1.0,Xslt 2.0,我需要通过比较多个XML来创建报告。有base.xml和多个分块xml。实际上,这些分块xml是base.xml的转换子集。 我的文件夹结构 Folder A - base.xml Folder B - metadata.xml(all the references to chuncked maintained here) Folder chunked - a.xml, b.xml, c.xml Base.xml <SchoolRoster> <department&g

我需要通过比较多个XML来创建报告。有base.xml和多个分块xml。实际上,这些分块xml是base.xml的转换子集。 我的文件夹结构

 Folder A - base.xml
 Folder B - metadata.xml(all the references to chuncked maintained here)
 Folder chunked - a.xml, b.xml, c.xml
Base.xml

<SchoolRoster>
<department>
    <name>Science</name>
    <location>LON</location>
    <Student>
        <rollNum>001</rollNum>
        <name>John</name>
        <age>14</age>
        <course>
            <refnum>A1</refnum>
            <math>A</math>
            <english>B</english>
            <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>
        </course>
        <course>
            <refnum>B1</refnum>
            <government>A+</government>
            <math>A</math>
            <english>B</english>
        </course>
    </Student>
    <Student>
        <rollNum>002</rollNum>
        <name>Tom</name>
        <age>13</age>
        <course>
            <refnum>C1</refnum>
            <gym>A</gym>
            <geography>incomplete</geography>
            <metas>
                <meta>
                    <name>x</name>
                    <value>2</value>
                </meta>
                <meta>
                    <name>y</name>
                    <value>1</value>
                </meta>
            </metas>
        </course>
    </Student>
</department>
<department>
    <name>History</name>
    <location>OXE</location>
    <Student>
        <rollNum>001</rollNum>
        <name>John</name>
        <age>14</age>
        <course>
            <refnum>A1</refnum>
            <math>A</math>
            <english>B</english>
            <metas>
                <meta>
                    <name>x</name>
                    <value>0</value>
                </meta>
                <meta>
                    <name>y</name>
                    <value>1</value>
                </meta>
            </metas>
        </course>
        <course>
            <refnum>B1</refnum>
            <government>A+</government>
            <math>A</math>
            <english>B</english>
        </course>
    </Student>
    <Student>
        <rollNum>006</rollNum>
        <name>Harry</name>
        <age>13</age>
        <course>
            <gym>A</gym>
            <geography>incomplete</geography>
            <metas>
                <meta>
                    <name>x</name>
                    <value>2</value>
                </meta>
                <meta>
                    <name>y</name>
                    <value>1</value>
                </meta>
            </metas>
        </course>
    </Student>
</department>
我正在尝试以下操作,但不确定如何为每个循环执行多次操作:

 <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:output method="html"/>
<xsl:template match="/">
    <html>
        <head> </head>
        <body>
            <xsl:apply-templates select="node()|@*"/>
        </body>
    </html>
</xsl:template>
<xsl:template match="department">
    <xsl:variable name="depName">
        <xsl:value-of select="name"/>
    </xsl:variable>
    <xsl:variable name="depLocation">
        <xsl:value-of select="location"/>
    </xsl:variable>
    <table style="width:100%">
        <tr>
            <td>Department Name</td>
            <td>
                <xsl:value-of select="$depName"/>
            </td>
            <td/>
            <td/>
            <td/>
            <td/>
        </tr>
        <tr>
            <td>Department Location</td>
            <td>
                <xsl:value-of select="$depLocation"/>
            </td>
            <td/>
            <td/>
            <td/>
            <td/>
        </tr>
        <xsl:for-each select="Student">
            <xsl:variable name="rollNum" select="rollNum"/>
            <xsl:variable name="metaXML"
                select="document('metadata.xml')/metadata/studentgroup[@category='science']/reference/@href"/>
            <xsl:variable name="chuckedXML"/>
            <tr>
                <td>Roll Number</td>
                <td>
                    <xsl:value-of select="rollNum"/>
                </td>
                <td>
                    <xsl:value-of select="$metaXML"/>
                </td>
                <td/>
                <td/>
                <td/>
            </tr>
            <tr>
                <td/>
                <td/>
                <td/>
                <td>Base XML</td>
                <td>Chuncked XML</td>
                <td>Equal?</td>
            </tr>

        </xsl:for-each>

    </table>
</xsl:template>

<xsl:template match="text()"/>

部门名称
部门位置
卷号
基本XML
压缩XML
平等?

我在这里尝试:

  • 对于base.xml中的每个“department/name”,请匹配metadata.xml中正确的metadata/studentgroup/@类别

  • 对于每个部门/student/@rollNum,请使用chucked文件“metadata/studentgroupp[@category]/reference”查找匹配的分块xml“learner/ref”

  • 比较这些值

  • 类似地,循环使用“metas/meta”标记,其中“name”应该是唯一标识符


  • 这里有一些未经完善的尝试来解决这个问题,不幸的是,输入样本中的元素顺序不同(
    age
    name
    name
    age
    ),因此无法简单地基于位置进行比较,而且元素名称部分不同(
    meta
    info
    )因此,对于这些元素,您需要额外的模板

    <?xml version="1.0" encoding="UTF-8"?>
    <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="meta-uri" as="xs:string" select="'test2016032202.xml'"/>
        <xsl:param name="meta-doc" as="document-node()" select="doc($meta-uri)"/>
    
        <xsl:key name="cat" match="metadata/studentgroup" use="@category"/>
        <xsl:key name="stud" match="learner" use="ref"/>
    
        <xsl:key name="meta-compare" match="learner/course/metas/info" use="name"/>
    
        <xsl:output method="html" indent="yes"/>
    
        <xsl:template match="/">
            <html>
                <head>
                    <title>Test</title>
                </head>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
    
        <xsl:template match="department">
            <table border="1">
                <thead>
                    <tr>
                        <th>Department Name</th>
                        <th colspan="5">
                            <xsl:value-of select="name"/>
                        </th>
                    </tr>
                    <tr>
                        <th>Department Location</th>
                        <th colspan="5">
                            <xsl:value-of select="location"/>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <xsl:for-each select="Student">
                        <xsl:variable name="student" select="."/>
                        <xsl:variable name="student-chunk"
                            select="
                                for $ref-doc in document(key('cat', lower-case(../name), $meta-doc)/reference/@href)
                                return
                                    key('stud', rollNum, $ref-doc)"/>
                        <tr>
                            <th>Roll Number</th>
                            <th colspan="5">
                                <xsl:value-of select="rollNum"/>
                            </th>
                        </tr>
                        <tr>
                            <td colspan="3"/>
                            <th>Base XML</th>
                            <th>Chuncked XML</th>
                            <th>Equal?</th>
                        </tr>
                        <xsl:apply-templates select="* except rollNum">
                            <xsl:with-param name="compare-parent" select="$student-chunk"/>
                        </xsl:apply-templates>
    
                    </xsl:for-each>
                </tbody>
            </table>
        </xsl:template>
    
        <xsl:template match="Student//*[*]">
            <xsl:param name="compare-parent"/>
            <xsl:variable name="pos" as="xs:integer">
                <xsl:number/>
            </xsl:variable>
            <xsl:variable name="element-to-compare" select="$compare-parent/*[node-name(.) eq node-name(current())][$pos]"/>
            <tr>
                <td colspan="2"/>
                <th colspan="4">
                    <xsl:value-of select="local-name()"/>
                </th>
            </tr>
            <xsl:apply-templates select="*">
                <xsl:with-param name="compare-parent" select="$element-to-compare"></xsl:with-param>
            </xsl:apply-templates>
        </xsl:template>
    
        <xsl:template match="Student//*[not(*)]">
            <xsl:param name="compare-parent"/>
            <xsl:variable name="pos" as="xs:integer">
                <xsl:number/>
            </xsl:variable>
            <xsl:variable name="element-to-compare"
                select="$compare-parent/*[node-name(.) eq node-name(current())][$pos]"/>
            <tr>
                <td colspan="2"/>
                <th>
                    <xsl:value-of select="local-name()"/>
                </th>
                <td>
                    <xsl:value-of select="."/>
                </td>
                <td>
                    <xsl:value-of select="$element-to-compare"/>
                </td>
                <td>
                    <xsl:value-of select=". = $element-to-compare"/>
                </td>
            </tr>
        </xsl:template>
    
        <xsl:template match="Student/course/metas/meta" priority="5">
            <xsl:param name="compare-parent"/>
            <xsl:variable name="element-to-compare" select="key('meta-compare', name, $compare-parent)"/>
            <tr>
                <td colspan="3" align="right">
                    <xsl:value-of select="name"/>
                </td>
                <td>
                    <xsl:value-of select="value"/>
                </td>
                <td>
                    <xsl:value-of select="$element-to-compare/value"/>
                </td>
                <td>
                    <xsl:value-of select="value = $element-to-compare/value"/>
                </td>
            </tr>
        </xsl:template>
    
    </xsl:stylesheet>
    
    
    试验
    部门名称
    部门位置
    卷号
    基本XML
    压缩XML
    平等?
    
    我在这里试图说明的逻辑是:1。对于每个“部门/名称”,从metadata.xml中选择正确的metadata/studentgroup/@category。2.对于每个部门/student/@rollNum,找到包含文件“metadata/studentgroup/refence”的“learner/ref”。3.比较这些值。请使用问题下方的编辑链接添加新信息,而不是在评论中。谢谢。更新了问题。太棒了!感谢您提供解决方案。要理解这一点并将其实现到我的真实场景中需要一段时间。我可能有几个问题。非常感谢。如何选择不匹配的键。如果我在a.xml xyz和abc中添加了另一个标记,那么如何将其打印在我的chuncked xml列中。如果使用,它将选择当前节点而不是关键点。
     <learner>
    <ref>002</ref>
    <name>Tom</name>
    <age>13</age>
    <course>
        <refnum>C1</refnum>
        <gym>A</gym>
        <geography>incomplete</geography>
        <metas>
            <info>
                <name>x</name>
                <value>2</value>
            </info>
            <info>
                <name>y</name>
                <value>1</value>
            </info>
        </metas>
    </course>
    
    <learner>
    <ref>006</ref>
    <name>Harry</name>
    <age>13</age>
    <course>
        <gym>A</gym>
        <geography>incomplete</geography>
        <metas>
            <info>
                <name>x</name>
                <value>2</value>
            </info>
            <info>
                <name>y</name>
                <value>1</value>
            </info>
        </metas>
    </course>
    
            Department Name     Science                                     
            Department Location LON                                     
            Roll Number         oo1             
            ---------------------------------------------------------                       
                                    Base XML   Chucked XML      Equal?
            Name                        John        John        Yes
            Age                         14          14          Yes
            Course A1                                               
                    Math                A           B           No
                    English             B           B           Yes
                    Meta x                                      
                            name        x           x           Yes
                            value       0           o           Yes
                    Meta y                                      
                            name        y           y           Yes
                            value       1           1           Yes
            Course B1                                               
                    Government          A+          A+          Yes
                    Math                A           A           Yes
                    English             B           B           Yes
            ---------------------------------------------------------                                               
            Department Name         Science                                     
            Department Location     LON                                     
            Roll Number             oo2                                     
            ---------------------------------------------------------
                                    Base XML   Chucked XML      Equal?                      
            Name                        Tom         Tomcat      No
            Age                         13          13          Yes
            Course C1                                               
                    gym                 A           A           Yes
                    geography   incomplete          incomplete  Yes
                    Meta x                                      
                            name        x           x           Yes
                            value       2           2           Yes
                    Meta y                                      
                            name        y           y           Yes
                            value       1           1           Yes
                    Meta z                                      
                            name        z           NA          NO
                            value       1           NA          NO
            ---------------------------------------------------------
    
     <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:output method="html"/>
    <xsl:template match="/">
        <html>
            <head> </head>
            <body>
                <xsl:apply-templates select="node()|@*"/>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="department">
        <xsl:variable name="depName">
            <xsl:value-of select="name"/>
        </xsl:variable>
        <xsl:variable name="depLocation">
            <xsl:value-of select="location"/>
        </xsl:variable>
        <table style="width:100%">
            <tr>
                <td>Department Name</td>
                <td>
                    <xsl:value-of select="$depName"/>
                </td>
                <td/>
                <td/>
                <td/>
                <td/>
            </tr>
            <tr>
                <td>Department Location</td>
                <td>
                    <xsl:value-of select="$depLocation"/>
                </td>
                <td/>
                <td/>
                <td/>
                <td/>
            </tr>
            <xsl:for-each select="Student">
                <xsl:variable name="rollNum" select="rollNum"/>
                <xsl:variable name="metaXML"
                    select="document('metadata.xml')/metadata/studentgroup[@category='science']/reference/@href"/>
                <xsl:variable name="chuckedXML"/>
                <tr>
                    <td>Roll Number</td>
                    <td>
                        <xsl:value-of select="rollNum"/>
                    </td>
                    <td>
                        <xsl:value-of select="$metaXML"/>
                    </td>
                    <td/>
                    <td/>
                    <td/>
                </tr>
                <tr>
                    <td/>
                    <td/>
                    <td/>
                    <td>Base XML</td>
                    <td>Chuncked XML</td>
                    <td>Equal?</td>
                </tr>
    
            </xsl:for-each>
    
        </table>
    </xsl:template>
    
    <xsl:template match="text()"/>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <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="meta-uri" as="xs:string" select="'test2016032202.xml'"/>
        <xsl:param name="meta-doc" as="document-node()" select="doc($meta-uri)"/>
    
        <xsl:key name="cat" match="metadata/studentgroup" use="@category"/>
        <xsl:key name="stud" match="learner" use="ref"/>
    
        <xsl:key name="meta-compare" match="learner/course/metas/info" use="name"/>
    
        <xsl:output method="html" indent="yes"/>
    
        <xsl:template match="/">
            <html>
                <head>
                    <title>Test</title>
                </head>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
    
        <xsl:template match="department">
            <table border="1">
                <thead>
                    <tr>
                        <th>Department Name</th>
                        <th colspan="5">
                            <xsl:value-of select="name"/>
                        </th>
                    </tr>
                    <tr>
                        <th>Department Location</th>
                        <th colspan="5">
                            <xsl:value-of select="location"/>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <xsl:for-each select="Student">
                        <xsl:variable name="student" select="."/>
                        <xsl:variable name="student-chunk"
                            select="
                                for $ref-doc in document(key('cat', lower-case(../name), $meta-doc)/reference/@href)
                                return
                                    key('stud', rollNum, $ref-doc)"/>
                        <tr>
                            <th>Roll Number</th>
                            <th colspan="5">
                                <xsl:value-of select="rollNum"/>
                            </th>
                        </tr>
                        <tr>
                            <td colspan="3"/>
                            <th>Base XML</th>
                            <th>Chuncked XML</th>
                            <th>Equal?</th>
                        </tr>
                        <xsl:apply-templates select="* except rollNum">
                            <xsl:with-param name="compare-parent" select="$student-chunk"/>
                        </xsl:apply-templates>
    
                    </xsl:for-each>
                </tbody>
            </table>
        </xsl:template>
    
        <xsl:template match="Student//*[*]">
            <xsl:param name="compare-parent"/>
            <xsl:variable name="pos" as="xs:integer">
                <xsl:number/>
            </xsl:variable>
            <xsl:variable name="element-to-compare" select="$compare-parent/*[node-name(.) eq node-name(current())][$pos]"/>
            <tr>
                <td colspan="2"/>
                <th colspan="4">
                    <xsl:value-of select="local-name()"/>
                </th>
            </tr>
            <xsl:apply-templates select="*">
                <xsl:with-param name="compare-parent" select="$element-to-compare"></xsl:with-param>
            </xsl:apply-templates>
        </xsl:template>
    
        <xsl:template match="Student//*[not(*)]">
            <xsl:param name="compare-parent"/>
            <xsl:variable name="pos" as="xs:integer">
                <xsl:number/>
            </xsl:variable>
            <xsl:variable name="element-to-compare"
                select="$compare-parent/*[node-name(.) eq node-name(current())][$pos]"/>
            <tr>
                <td colspan="2"/>
                <th>
                    <xsl:value-of select="local-name()"/>
                </th>
                <td>
                    <xsl:value-of select="."/>
                </td>
                <td>
                    <xsl:value-of select="$element-to-compare"/>
                </td>
                <td>
                    <xsl:value-of select=". = $element-to-compare"/>
                </td>
            </tr>
        </xsl:template>
    
        <xsl:template match="Student/course/metas/meta" priority="5">
            <xsl:param name="compare-parent"/>
            <xsl:variable name="element-to-compare" select="key('meta-compare', name, $compare-parent)"/>
            <tr>
                <td colspan="3" align="right">
                    <xsl:value-of select="name"/>
                </td>
                <td>
                    <xsl:value-of select="value"/>
                </td>
                <td>
                    <xsl:value-of select="$element-to-compare/value"/>
                </td>
                <td>
                    <xsl:value-of select="value = $element-to-compare/value"/>
                </td>
            </tr>
        </xsl:template>
    
    </xsl:stylesheet>