Xslt 比较每个XML使用的多个XML
我需要通过比较多个XML来创建报告。有base.xml和多个分块xml。实际上,这些分块xml是base.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
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
平等?
我在这里尝试:
这里有一些未经完善的尝试来解决这个问题,不幸的是,输入样本中的元素顺序不同(
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>