2017-05-12 1 views
0

Datei a.xml mit:in einem, Xslt

<?xml version="1.0" encoding="UTF-8"?> 
<TABLE NAME="pivot.cs"> 
    <DATA RECORDS="2"> 
     <RECORD ID="1"> 
     <INTERNALID>5510</INTERNALID> 
     <SOMED>1</SOMED> 
     <PEMED>1</PEMED> 
     <CODAL>PLACEHOLD</CODAL> 
     </RECORD> 
     <RECORD ID="2"> 
     <INTERNALID>5511</INTERNALID> 
     <SOMED>1</SOMED> 
     <PEMED>1</PEMED> 
     <CODAL>PLACEHOLD</CODAL> 
     </RECORD> 
     <INTERNALID>5537</INTERNALID> 
     <SOMED>1</SOMED> 
     <PEMED>1</PEMED> 
     <CODAL>PLACEHOLD</CODAL> 
    </DATA> 
</TABLE> 

Datei b.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<TABLE NAME="ALT.CS"> 
    <DATA RECORDS="20"> 
     <RECORD ID="53"> 
     <RECNO>5510</RECNO> 
     <TOBEEXTRACTED>TIM</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="53"> 
     <RECNO>5510</RECNO> 
     <TOBEEXTRACTED>KLM</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="54"> 
     <RECNO>5510</RECNO> 
     <TOBEEXTRACTED>KAB</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="55"> 
     <RECNO>5511</RECNO> 
     <TOBEEXTRACTED>BUS WEE</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="59"> 
     <RECNO>5512</RECNO> 
     </RECORD> 
     <RECORD ID="60"> 
     <RECNO>5513</RECNO> 
     </RECORD> 
     <RECORD ID="5511"> 
      <RECNO>5598</RECNO> 
      <TOBEEXTRACTED>FBV</TOBEEXTRACTED> 
     </RECORD> 
     </RECORD> 
    </DATA> 
</TABLE> 

und Ausgabedatei sollte, wird die Datei a.xml, aber mit dem Text TOBEEXTRACTED Elements angefügt in [], angepasst, wenn ein oder zwei mal:

<?xml version="1.0" encoding="UTF-8"?> 
<TABLE NAME="pivot.cs"> 
    <DATA RECORDS="2"> 
     <RECORD ID="1"> 
     <INTERNALID>5510</INTERNALID> 
     <SOMED>1</SOMED> 
     <PEMED>1</PEMED> 
     <CODAL>PLACEHOLD</CODAL> 
     </RECORD> 
     <RECORD ID="2"> 
     <INTERNALID>5511</INTERNALID> 
     <SOMED>1</SOMED> 
     <PEMED>1</PEMED> 
     <CODAL>PLACEHOLD [BUS WEE]</CODAL> 
     </RECORD> 
     <INTERNALID>5537</INTERNALID> 
     <SOMED>1</SOMED> 
     <PEMED>1</PEMED> 
     <CODAL>PLACEHOLD</CODAL> 
    </DATA> 
</TABLE> 

auch wäre es sehr hilfreich sein, wenn wir eine txt-Datei als Ausgabe haben könnten, das hätte die folgenden Informationen: aus Datei a.xml,

INTERNALID: 5511 (and all the rest in a normal xml file) was matched. 
INTERNALID: 5510 was matched more than two times, so no join took place. 
INTERNALID: 5537 did not match 
RECNO 5512 did not have a TOBEEXTRACTED element. 
+0

Können Sie zumindest die Eingabe bearbeiten und wollte Ausgangsabtastwerte Beispiele zeigen der Fälle, an denen Sie interessiert sind (Elemente übereinstimmen, nicht übereinstimmen, mehr als zwei übereinstimmen, ohne TOBEXTRACTED-Element abgeglichen? –

+0

) Denken Sie auch daran, Ihren Versuch zu zeigen, dies mit XSLT 2.0 zu lösen, können Sie den Querverweis einfach lösen mit einem Schlüssel '' und dann '' xsl: template match = "DATA/RECORD [key ('ref ', INTERNALID, Dok ('fileb.xml')]/CODAL ">' –

+0

hoffe, es ist jetzt klarer, danke – duxok

Antwort

0

Wenn Sie einen Schlüssel verwenden, der in einem Kommentar vorgeschlagen können Sie Elemente verweisen und passen Sie wie folgt vor:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:param name="doc2"> 
     <TABLE NAME="ALT.CS"> 
    <DATA RECORDS="20"> 
     <RECORD ID="53"> 
     <RECNO>5510</RECNO> 
     <TOBEEXTRACTED>TIM</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="53"> 
     <RECNO>5510</RECNO> 
     <TOBEEXTRACTED>KLM</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="54"> 
     <RECNO>5510</RECNO> 
     <TOBEEXTRACTED>KAB</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="55"> 
     <RECNO>5511</RECNO> 
     <TOBEEXTRACTED>BUS WEE</TOBEEXTRACTED> 
     </RECORD> 
     <RECORD ID="59"> 
     <RECNO>5512</RECNO> 
     </RECORD> 
     <RECORD ID="60"> 
     <RECNO>5513</RECNO> 
     </RECORD> 
     <RECORD ID="5511"> 
      <RECNO>5598</RECNO> 
      <TOBEEXTRACTED>FBV</TOBEEXTRACTED> 
     </RECORD> 

    </DATA> 
</TABLE> 
    </xsl:param> 

    <xsl:key name="ref" match="DATA/RECORD[TOBEEXTRACTED]" use="RECNO"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="DATA/RECORD[key('ref', INTERNALID, $doc2)]/CODAL"> 
     <xsl:copy> 
      <xsl:apply-templates select="node(), key('ref', ../INTERNALID, $doc2)/TOBEEXTRACTED"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="DATA/RECORD[not(key('ref', INTERNALID, $doc2))]"/> 

    <xsl:template match="TOBEEXTRACTED"> 
     <xsl:value-of select="concat(' [', ., ']')"/> 
    </xsl:template> 

</xsl:transform> 

, dass die Ausgabe gibt Ihnen bei http://xsltransform.net/a9Giwy gebucht haben. Dort habe ich eine xsl:param name="doc2" mit Inline-Inhalten verwendet, aber Sie können natürlich <xsl:param name="doc2" select="doc('fileb.xml')"/> stattdessen verwenden.

Wie in einem bearbeiten die Frage zusätzlich als markiert wurde habe ich auch versucht, es zu implementieren mit der xsl:merge Anweisung dieser Version:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math" 
    version="3.0"> 

    <xsl:param name="doc2-uri" as="xs:string" select="'test201705120102.xml'"/> 

    <xsl:mode on-no-match="shallow-copy"/> 

    <xsl:output indent="yes"/> 

    <xsl:template match="TABLE/DATA"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:merge> 
       <xsl:merge-source name="internal" select="RECORD" > 
        <xsl:merge-key select="INTERNALID"/> 
       </xsl:merge-source> 
       <xsl:merge-source name="recno" select="doc($doc2-uri)//RECORD"> 
        <xsl:merge-key select="RECNO"/> 
       </xsl:merge-source> 
       <xsl:merge-action> 
        <xsl:if test="current-merge-group('internal') and current-merge-group('recno')"> 
         <xsl:copy> 
          <xsl:copy-of select="@*, * except CODAL"/> 
          <CODAL> 
           <xsl:value-of select="CODAL, current-merge-group('recno')/TOBEEXTRACTED/('[' || . || ']')"/> 
          </CODAL> 
         </xsl:copy> 
        </xsl:if> 
       </xsl:merge-action> 
      </xsl:merge> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Eigentlich möchte ich alle Änderungen in der ursprünglichen XML versehentlich in der Ausgabedatei überschrieben werden, Ich habe nur die geänderten Aufzeichnungen aufgenommen und zuletzt, wie ich die obigen Beispiele ändern könnte, um einen Bericht darüber zu erhalten, was geändert wurde und was nicht? – duxok

+0

Ich bin mir sicher, XSLT ist eine Programmiersprache und kann verwendet werden, um die Details zu melden, aber Ihre Frage hat nicht einmal klar gemacht, ob und wo Sie diese Informationen in dem Ergebnisbeispiel haben möchten und ob Sie es in einem enthalten möchten zweite Ergebnisdatei, so konzentrierte ich mich darauf, den Teil zu beantworten, der eine klare Anforderungsbeschreibung zu haben schien. Wenn Sie Ihre Frage bearbeiten und erklären und zeigen, wo/wie Sie die Informationen haben wollen, dann sind wir sicher, dass wir mit dem Code helfen können. –

+0

haben meine Frage neu beschrieben, mit der Hoffnung, dass es jetzt klarer ist – duxok

0

Diese Art der Zusammenführung oft erreicht xsl werden kann: for-each-group:

<xsl:for-each-group select="$doc1//REC, $doc2//REC" group-by="RECNO"> 
    ... 
</xsl:for-each-group> 

im Körper, Strom -group() enthält die Datensätze aus beiden Dateien mit dem erforderlichen Schlüssel. Sie können sie trennen mit zum Beispiel

<xsl:variable name="doc1rec" select="current-group()[(/) is $doc1]"/> 
<xsl:variable name="doc2rec" select="current-group()[(/) is $doc2]"/> 

und dann sollte die restliche Verarbeitung einfach sein, wenn Sie die Logik verstehen (was ich nicht).