我需要通过比较多个xml来创建报告。有基础.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
基地.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>
元数据.xml
<metadata>
<studentgroup category="science">
<reference href="chunked/a.xml"/>
<reference href="chunked/b.xml"/>
</studentgroup>
<studentgroup category="history">
<reference href="chunked/a.xml"/>
<reference href="chunked/c.xml"/>
</studentgroup>
答.xml
<learner>
<ref>001</ref>
<name>John</name>
<age>14</age>
<course>
<refnum>A1</refnum>
<math>B</math>
<english>B</english>
<metas>
<info>
<name>x</name>
<value>0</value>
</info>
<info>
<name>y</name>
<value>1</value>
</info>
</metas>
</course>
<course>
<refnum>B1</refnum>
<government>A+</government>
<math>A</math>
<english>B</english>
</course>
b.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>
c.xml
<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>
所需输出:(无法放置 HTML 代码)
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
---------------------------------------------------------
我正在尝试以下操作,但不确定如何执行多个 for-each 循环:
<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()"/>
我在这里尝试:
对于 Base 中的每个"部门/名称".xml匹配元数据.xml中的正确元数据/学生组/@category。
对于每个部门/学生/@rollNum与压缩文件"元数据/学生组P[@category]/参考"匹配,找到匹配的分块XML"学习者/参考"。
比较值。
同样,循环遍历"元/元"标签,其中"名称"应该是唯一标识符。
这里有一些未经修饰的尝试来解决,不幸的是,输入样本具有不同顺序的元素(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>