XSLT: Merging two log files with different structure and time-representation

前端 未结 1 1752
面向向阳花
面向向阳花 2020-12-20 05:38

As asked by Dimitre Novatchev I created a new question, as some parts of the old question changed.

(Link to the old question: Merging two different XML log files (t

相关标签:
1条回答
  • 2020-12-20 06:22
    <?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"
        xmlns:m="http://www.example.com/"
        exclude-result-prefixes="xs"
        version="2.0">
    
        <xsl:output indent="yes" method="xml"/>
    
        <!-- The two source-documents. -->
        <xsl:variable name="doc1" select="doc('log1.xml')"/>
        <xsl:variable name="doc2" select="doc('log2.xml')"/>
    
        <!-- Timezone adjustment -->
        <xsl:variable name="timezoneAdjustment" select="1"/>
    
        <!-- Root template to start the transformation. -->
        <xsl:template match="/">
            <!-- Transform and collect all the elements -->
            <xsl:variable name="data" as="node()*">
                <xsl:apply-templates select="$doc1/itemList/item"/>
                <xsl:apply-templates select="$doc2/messageList/Message"/>
            </xsl:variable>
            <!-- Sort by the timestamp, and discard the wrapper. -->
            <itemList>
                <xsl:for-each select="$data">
                    <xsl:sort select="@timestamp" data-type="number"/>
                    <xsl:copy-of select="item"/>
                </xsl:for-each>
            </itemList>
        </xsl:template>
    
        <!--
            Template to transform <item> elements in the first format.
            It just parses the date, and adds a wrapper with the timestamp.
        -->
        <xsl:template match="item[date]">
            <xsl:variable name="dateTimeString" select="date" as="xs:string"/>
            <xsl:variable name="datePart" select="substring-before($dateTimeString,' ')"/>
            <xsl:variable name="day" select="xs:integer(substring-before($datePart,'.'))"/>
            <xsl:variable name="month" select="xs:integer(substring-before(substring-after($datePart,'.'),'.'))"/>
            <xsl:variable name="year" select="xs:integer(substring-after(substring-after($datePart,'.'),'.'))"/>
            <xsl:variable name="timePart" select="substring-after($dateTimeString,' ')"/>
            <xsl:variable name="reformatted" select="concat(format-number($year,'0000'),'-',format-number($month,'00'),'-',format-number($day,'00'),'T',$timePart)"/>
            <xsl:variable name="timestamp" select="( xs:dateTime($reformatted) - xs:dateTime('1970-01-01T00:00:00') - $timezoneAdjustment * xs:dayTimeDuration('PT1H') ) div xs:dayTimeDuration('PT0.001S')"/>
            <wrapper timestamp="{$timestamp}">
                <xsl:copy-of select="self::*"/>
            </wrapper>
        </xsl:template>
    
        <!--
            Template to transform <Message> elements in the second log format.
            It generates an item with the date, and wraps it with the timestamp.
        -->
        <xsl:template match="Message[originator/originatorPosition/timeStamp]">
            <xsl:variable name="timestamp" select="originator/originatorPosition/timeStamp" as="xs:integer"/>
            <xsl:variable name="date" select="xs:dateTime('1970-01-01T00:00:00') + $timezoneAdjustment * xs:dayTimeDuration('PT1H') + $timestamp * xs:dayTimeDuration('PT0.001S')"/>
            <wrapper timestamp="{$timestamp}">
                <item>
                    <date>
                        <xsl:value-of select="format-dateTime($date,'[D01].[M01].[Y0001] [H01]:[m01]:[s01].[f001]')"/>
                    </date>
                    <m:Message type="recieved">
                        <xsl:copy-of select="*"/>
                    </m:Message>
                </item>
            </wrapper>
        </xsl:template>
    
    </xsl:stylesheet>
    

    EDIT: I added a variable for timezone adjustment for Messages.

    EDIT: Fixed the attribute names, so the items will sort correctly.

    0 讨论(0)
提交回复
热议问题