2009-11-20 12 views
21

मैं एक्सएसएल/एक्सएसएलटी का उपयोग कर दो एक्सएमएल फाइलों या नोड्स के बीच अंतर की गणना करना चाहता हूं। क्या कोई स्टाइलशीट आसानी से उपलब्ध है या इसे करने का कोई आसान तरीका है?एक्सएमएल डिफ: एक्सएसएलटी का उपयोग कर एक्सएमएल डिफ कैसे उत्पन्न करें?

+3

+1 बस, BTW XSLT का कौन सा संस्करण थे आप में काम करने के लिए इस की तलाश में – AnthonyWJones

+0

लक्ष्य diff होगा एक ही एक्सएमएल फ़ाइल में दो नोड्स, यह अधिक व्यवहार्य है? – Vincent

+0

आपको एक्सएमएल शर्तों में बराबर और अलग-अलग साधनों को परिभाषित करना होगा। एक संदर्भ के रूप में इस सवाल को देखें http://stackoverflow.com/questions/4546190/compare-two-xml-files-with-xslt –

उत्तर

6

दिलचस्प सवाल! मैंने एक बार दो एक्सएमएल स्रोतों को शामिल करने की कोशिश की, और मेरा अनुभव यह था कि वहां कोई रास्ता नहीं है।

आप उपयोगकर्ता निर्मित कार्यों को शामिल करने के लिए एक्सएसएल की सुविधा का उपयोग कर सकते हैं, और वास्तव में कुछ गड़बड़ कर सकते हैं। लेकिन मैं वास्तव में इसे नहीं देख सकता।

अगर मुझे ऐसा कुछ करना था, तो मैं दो एक्सएमएल फाइलों को डीओएम 4 जे का उपयोग करके समानांतर में संसाधित करता हूं, जो मुझे आसानी से कोड को क्रमबद्ध रूप से ट्रैक करने और विस्तार से उप-प्रश्न करने देता है।

एक्सएसएलटी में ऐसा करने की कोशिश करने से आप या तो एक प्रतिभा बन जाएंगे या आपको पागलपन में ले जाएंगे।

2

एक्सएसएलटी डाटा-संचालित है, यानी, यह एक्सएसएल स्टाइलशीट में टेम्पलेट मैचों की तलाश में एकल स्रोत एक्सएमएल फ़ाइल शीर्ष से नीचे जाता है। टेम्पलेट्स वास्तव में नहीं जानते कि वे डेटा में कहां हैं, वे मिलान करते समय बस अपना कोड चलाते हैं। आप किसी अन्य XML स्रोत का संदर्भ दे सकते हैं, लेकिन प्रोग्राम मूल स्रोत के ट्रैवर्सल के अनुसार चलाएगा।

तो जब आप <blarg> के एनएच बच्चे तत्व पर पहुंचते हैं, उदाहरण के लिए, आप document() फ़ंक्शन का उपयोग करके दूसरे XML में <blarg> के nth बच्चे को देख सकते हैं। लेकिन इसकी उपयोगिता आपके एक्सएमएल की संरचना और आप जो तुलना करने की कोशिश कर रहे हैं उसकी संरचना पर निर्भर करती है।

यह व्यवहार सबसे पारंपरिक स्क्रिप्ट के विपरीत है, जो प्रोग्राम कोड को ऊपर से नीचे चलाता है, निर्देश दिए जाने पर डेटा फ़ाइल पर कॉल करता है। उत्तरार्द्ध - पुल प्रोसेसिंग - आपको शायद दो एक्सएमएल स्रोतों की तुलना करने की आवश्यकता है। जैसे ही कोई फर्क पड़ता है, एक्सएसएलटी तुलना में टूट जाएगा।

1

ऐसा करने के तरीके हैं, लेकिन मैं यह नहीं कहूंगा कि यह आसान है।

अतीत मैं एक खुला स्रोत उपयोगिता diffmk कहा जाता है का उपयोग किया है में, यह अतिरिक्त टैग दिखा क्या/जोड़ दिया गया है हटा दिया साथ एक निर्गम एक्सएमएल पैदा करता है ...

मैं एक अतिरिक्त स्टाइलशीट तो यह कन्वर्ट करने के लिए लिखना पड़ा एक और अधिक पढ़ने योग्य एचटीएमएल रिपोर्ट में।

XMLSpy डिफ कुत्ते जैसे कुछ भिन्न उपकरण अच्छे हैं, लेकिन महंगा हैं।

1

यह एक रहस्य नहीं है! यहां सामान्य चरण दिए गए हैं:

  1. @ कैरिलोनेटर इस बारे में सही है कि XSLT दस्तावेज़ों को कैसे संसाधित करता है। इसलिए इसे आसान बनाने के लिए हम आपके दस्तावेज़ों के दो संस्करणों को एक ऐसे दस्तावेज़ में जोड़ते हैं जिसका उपयोग आप अपने एक्सएसएलटी डिफ को चलाने के लिए कर सकते हैं (आप इसे बैश के साथ कमांड लाइन के माध्यम से कर सकते हैं, या जो भी प्रोग्रामिंग भाषा आप उपयोग कर रहे हैं, या फिर भी एक्सएसएलटी ट्रांसफॉर्म [पाइप])। यह सिर्फ एक कैप्सूलीकरण है:

    <diff_container> 
        <version1> 
         ... first version here 
        </version1> 
        <version2> 
         ... second version here 
        </version2> 
    </diff_container> 
    
  2. उसके बाद हम हमारी XSLT diff के माध्यम से इस दस्तावेज़ को चलाने, XSLT तो बस पेड़ traversing और दो संस्करणों के बीच नोड्स की तुलना का काम किया है। यह बहुत सरल से जा सकता है (क्या कोई तत्व बदल गया था? हटाया गया? हटाया गया?) अर्द्ध परिसर में। XPath की अच्छी समझ यह काफी सरल बनाती है।

    कुछ लोगों ने पहले कहा था, आप एक अलग वातावरण के अंदर काम कर रहे हैं ताकि आप डिफ डॉग जैसे उपकरणों की तुलना में सीमित हो। हालांकि एक्सएसएलटी में एल्गोरिदम होने का लाभ वास्तविक मूल्य भी हो सकता है।

आशा है कि इससे मदद मिलेगी। चीयर्स!

2

क्या आप diff मतलब देखना हो आइटम एक दस्तावेज़ (या नोड) में मौजूद हैं की तरह कुछ लेकिन एक और नहीं, तो आप xpath कुंजी (उपयोग कर सकते हैं) समारोह एक तिहाई पैरामीटर

<?xml version="1.0"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs ="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xsl xs"> 

<xsl:param name="doc2diff" required="yes"/> 
<!-- docB is root node of the "second" document --> 
<xsl:variable name="docB" select="document($doc2diff)"/> 
<!-- docA is the root node of the first document --> 
<xsl:variable name="docA" select="/"/> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
<xsl:key name="items" match="Item" use="someId"/> 

<xsl:template match="/"> 
<ListOfItems> 
    <In_A_NotIn_B> 
    <xsl:apply-templates select="Item"> 
    <xsl:with-param name="otherDocument" select="$docB"/> 
    </xsl:apply-templates> 
    </In_A_NotIn_B> 
    <In_B_NotIn_A> 
    <xsl:apply-templates select="Item"> 
    <xsl:with-param name="otherDocument" select="$docA"/> 
    </xsl:apply-templates> 
    </In_B_NotIn_A> 
</ListOfItems> 
</xsl:template> 

<xsl:template match="Item"> 
<xsl:param name="otherDocument"/> 
    <xsl:variable name="SOMEID" select="someId"/> 
    <xsl:if test="empty(key('items', $SOMEID, $otherDocument))"> 
    <xsl:copy-of select="."/> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet>` 
2

साथ है, तो यह वह जगह है स्टाइलशीट मैंने नोड्स और एट्रिब्यूट में अलग-अलग ऑर्डर के साथ दो एक्सएमएल फाइलों की तुलना करने के लिए लिखा है, यह दो लीफ फाइलें उत्पन्न करेगा जिसमें सभी लीफ नोड्स ऑर्डर ऑर्डर की सूची होगी। मतभेदों को जानने के लिए किसी भी टेक्स्ट तुलना टूल का उपयोग करें या जो भी आप चाहते हैं उसे करने के लिए एक्सएसएलटी बढ़ाया।

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

1

हाल ही में इस पद मिले लेकिन वैसे भी मैं इस तरह की समस्या के लिए मेरे समाधान प्रदान करेगे। मुझे @Vincent की आवश्यकता थी: 2 diferents XML फ़ाइलों की तुलना करना और उनके बीच अंतर को तुरंत देखें। एक त्वरित diff से मेल खाने वाली कई रेखाएं थीं क्योंकि फ़ाइलों को सॉर्ट नहीं किया गया था इसलिए मैंने XSLT का उपयोग करके फ़ाइलों को सॉर्ट करने का निर्णय लिया और फिर उदाहरण के लिए WinMerge का उपयोग करके मैन्युअल रूप से दो एक्सएमएल फ़ाइलों की तुलना करें (एक सरल यूनिक्स diff भी नौकरी कर सकता है)।

यहाँ XSLT कि मेरे एक्सएमएल फ़ाइल को सॉर्ट है:। यह की महत्वाकांक्षा के लिए

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output method="xml" indent="yes" encoding="UTF-8"/> 

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

</xsl:stylesheet> 
संबंधित मुद्दे