5 Stimmen

zwei Xml-Dateien mit Xslt vergleichen?

Ich habe 2 xml-Dateien. Wie kann ich vergleichen, ob beide Dateien gleich sind oder nicht, indem ich xslt verwende? Wenn nicht gleich bedeutet, wo die Änderungen havebeen auftreten, in der zweiten xml?

4voto

In XPath 2.0 konnten Sie einfach verwenden fn:deep-equal .

Dieses Stylesheet folgt dem gleichen Muster wie XSLT 1.0:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="pSource2" select="'emp2.xml'"/>
    <xsl:template match="/*">
        <xsl:variable name="vDeep-equal">
            <xsl:apply-templates select="." mode="deep-equal">
                <xsl:with-param name="pTarget" select="document($pSource2)/*"/>
            </xsl:apply-templates>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="normalize-space($vDeep-equal)">
                <xsl:text>Documents are different</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>Documents are deep equal</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*" mode="deep-equal">
        <xsl:param name="pTarget"/>
        <xsl:choose>
            <xsl:when test="$pTarget/self::* and
                            local-name()=local-name($pTarget) and
                            namespace-uri()=namespace-uri($pTarget) and
                            count(@*)=count($pTarget/@*) and
                            count(*|text()[normalize-space()]) =
                               count($pTarget/*|
                                     $pTarget/text()[normalize-space()])">
                <xsl:for-each select="@*">
                    <xsl:if test="$pTarget/@*[name()=name(current())] != .">
                        <xsl:text>false</xsl:text>
                    </xsl:if>
                </xsl:for-each>
                <xsl:for-each select="*|text()[normalize-space()]">
                    <xsl:variable name="vPosition" select="position()"/>
                    <xsl:apply-templates select="." mode="deep-equal">
                        <xsl:with-param name="pTarget"
                                        select="($pTarget/*|
                                                 $pTarget/text()
                                                    [normalize-space()])
                                                            [$vPosition]"/>
                    </xsl:apply-templates>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>false</xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="text()" mode="deep-equal">
        <xsl:param name="pTarget"/>
        <xsl:if test="not($pTarget/self::text() and
                      string() = string($pTarget))">
            <xsl:text>false</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

出力します。

Documents are different

0voto

Oded Punkte 475566

XSLT wird am besten verwendet für umwandelnd von einem XML-Dialekt zum anderen.

Um XML-Dateien zu vergleichen, würde ich einen XML-Parser auf Ihrer Plattform verwenden und die Dokumente damit vergleichen.

Sie ist möglich um die beiden zu vergleichen, aber ich würde davon abraten, wenn Sie andere Möglichkeiten haben.

0voto

Trunkate Punkte 31

Dies ist das Stylesheet, das ich geschrieben habe, um zwei XML-Dateien mit unterschiedlicher Reihenfolge der Knoten und Attribute zu vergleichen. Es erzeugt zwei Textdateien, die die geordnete Liste aller Blattknotenpfade enthalten. Verwenden Sie ein beliebiges Textvergleichstool, um die Unterschiede herauszufinden, oder erweitern Sie das XSLT, um zu tun, was Sie wollen.

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

<xsl:output method="text" indent="no" omit-xml-declaration="yes" name="output" />

<xsl:param name="OTHERFILENAME">xml_file_to_diff.xml</xsl:param>
<xsl:param name="ORIGINAL_OUTPUT_FILENAME">ORIGINAL.txt</xsl:param>
<xsl:param name="OTHER_OUTPUT_FILENAME">OTHER.txt</xsl:param>

<xsl:template match="/">
    <xsl:call-template name="convertXMLHierarchyToFullPath">
        <xsl:with-param name="node" select="*"/>
        <xsl:with-param name="filename" select="$ORIGINAL_OUTPUT_FILENAME"/>
    </xsl:call-template>
    <xsl:call-template name="convertXMLHierarchyToFullPath">
        <xsl:with-param name="node" select="document($OTHERFILENAME)/*"/>
        <xsl:with-param name="filename" select="$OTHER_OUTPUT_FILENAME"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="convertXMLHierarchyToFullPath">
    <xsl:param name="node"/>
    <xsl:param name="filename"/>

    <xsl:variable name="unorderedFullPath">
        <xsl:apply-templates select="$node"/>
    </xsl:variable>

    <xsl:result-document href="{$filename}" format="output">
        <xsl:for-each select="$unorderedFullPath/*">
            <xsl:sort select="@path" data-type="text"/>
            <xsl:value-of select="@path"/>
            <xsl:text>&#xA;</xsl:text>
        </xsl:for-each>
    </xsl:result-document>
</xsl:template>

<xsl:template match="*">
    <xsl:if test="not(*)">
        <leaf>
            <xsl:attribute name="path">
                <xsl:for-each select="ancestor-or-self::*">
                    <xsl:value-of select="name()"/>
                    <xsl:for-each select="@*">
                        <xsl:sort select="name()" data-type="text"/>
                        <xsl:text>[</xsl:text>
                        <xsl:value-of select="name()"/>
                        <xsl:text>:</xsl:text>
                        <xsl:value-of select="."/>
                        <xsl:text>]</xsl:text>
                    </xsl:for-each>
                    <xsl:text>/</xsl:text>
                </xsl:for-each>
                <xsl:value-of select="."/>
            </xsl:attribute>
        </leaf>
    </xsl:if>
    <xsl:apply-templates select="*"/>
</xsl:template>

</xsl:stylesheet>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X