2016-03-21 2 views
2

Мне нужно создать отчет, сравнив несколько xmls. Существует base.xml и несколько chunked xmls. На самом деле эти chunked xmls преобразуются подмножество base.xml. Моя структура папок.Сравнение нескольких xmls с использованием for-each

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> 

metadata.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> 

a.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 
     --------------------------------------------------------- 

Я пытаюсь следующий, но не уверен, как это сделать мультипликатор для-каждого цикла:

<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()"/> 

Я пытаюсь здесь:

  1. для каждого «отдела/name 'в файле base.xml соответствуют категории метаданных/studentgroup/@ в метаданных.xml.

  2. для каждого отдела/ученика/@ rollNum match with chucked file 'metadata/studentgroupp [@category]/reference' найти соответствующий chunked xml 'learner/ref'.

  3. сравнить значения.

  4. Аналогичным образом перебирают теги «metas/meta», где «имя» должно быть уникальным идентификатором.

+0

Логика Я пытаюсь поставить здесь: –

+0

1. для каждого «отдела/имя» правильно выбрать метаданные/studentgroup/@ категории от metadata.xml. 2.для каждого раздела/студента/@ rollNum матч с метафорическим файлом 'metadata/studentgroup/refence' найдите «ученик/ref». 3. Сравните значения. –

+1

Пожалуйста, используйте ссылку для редактирования ниже вопроса, чтобы добавить новую информацию, а не комментарии. – Dijkgraaf

ответ

0

Вот некоторые неполированный попытка решить, что, к сожалению, входные выборки имеют элементы в другом порядке (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> 
+0

Удивительный! спасибо за предоставление решения. Это займет некоторое время, чтобы понять это и реализовать его в моем реальном сценарии. У меня может быть несколько вопросов. большое спасибо. –

+0

как выбрать непревзойденные ключи. Если я добавлю еще один тег в a.xml xyz и abc, как его распечатать в моем столбце XML. Если я использую , он выбирает текущий узел, а не ключ. –

Смежные вопросы