我需要合并两个XML日志文件。一个日志文件包含具有位置更新的跟踪。另一个日志文件包含收到的消息。可以有多个收到的消息,而不会在两者之间进行位置更新。
两个日志都有时间戳:
跟踪的结构如下:
<item>
<date>14.7.2012 11:08:07.222</date>
<MyPosition>
// Position data
</MyPosition>
</item>
<item>
<date>14.7.2012 12:13:07.112</date>
<MyPosition>
// Position data
</MyPosition>
</item>
...
消息的结构如下:
<Message>
// some content of the message
<subTag>
<timeStamp>1342264087</timeStamp>
</subTag>
// other content of the message
</Message>
<Message>
// same as above
</Message>
...
在进行合并时,应该读取时间戳(也可以转换/比较“日期”和“时间戳”)以及按正确顺序添加的所有位置和消息。
位置数据可以按原样添加。但是,邮件应放在&lt; item&gt;内。标签,一个&lt; date&gt;应添加标签(基于消息的unix时间)和&lt; Message&gt;标签应替换为&lt; m:消息类型=“已收到”&gt;标签
不幸的是,不是“简单”的合并,特别是当日志文件的大小介于5 MB和700 MB之间时......: - /
结果可能如下所示:
<item>
<date>14.7.2012 11:08:07.222</date>
<MyPosition>
// Position data
</MyPosition>
</item>
<item>
<date>14.7.2012 11:09:10.867</date>
<m:Message type="received">
// content of the <Message>
</m:Message>
</item>
<item>
<date>14.7.2012 12:10:11.447</date>
<m:Message type="received">
// content of the former <Message>
</m:Message>
</item>
<item>
<date>14.7.2012 12:13:07.112</date>
<MyPosition>
// Position data
</MyPosition>
</item>
<item>
<date>14.7.2012 12:17:11.227</date>
<m:Message type="received">
// content of the former <Message>
</m:Message>
</item>
...
是否有支持合并的工具?或者有没有简单的方法来解决这个问题?
我非常感谢有关如何解决此事的任何提示。
答案 0 :(得分:1)
此XSLT 2.0转换(为方便起见,包含内联的小型消息日志示例):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:m="some:M" exclude-result-prefixes="xs m">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vDateU0" select="xs:dateTime('1970-01-01T00:00:00')"/>
<xsl:variable name="vMessages">
<Message> // some content of the message
<subTag>
<timeStamp>1342264087</timeStamp>
</subTag> // other content of the message
</Message>
<Message> // some content of the message2
<subTag>
<timeStamp>1342264089</timeStamp>
</subTag> // other content of the message2
</Message>
</xsl:variable>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="vProcessedMessages">
<xsl:apply-templates select="$vMessages/*"/>
</xsl:variable>
<xsl:variable name="vProcessedTrace">
<xsl:apply-templates select="/*/*"/>
</xsl:variable>
<xsl:perform-sort select="$vProcessedMessages/*|$vProcessedTrace/*">
<xsl:sort select="xs:dateTime(date)"/>
</xsl:perform-sort>
</xsl:template>
<xsl:template match="Message">
<xsl:variable name="vUnixDuration" select=
"concat('PT', */timeStamp, 'S')"/>
<item>
<date><xsl:sequence select=
"$vDateU0 + xs:dayTimeDuration($vUnixDuration)"/>
</date>
<m:Message type="received">
<xsl:sequence select="text()[1]"/>
</m:Message>
</item>
</xsl:template>
<xsl:template match="date/text()">
<xsl:variable name="vdatePart" select="substring-before(., ' ')"/>
<xsl:variable name="vYear" select=
"substring-after(substring-after($vdatePart, '.'), '.')"/>
<xsl:variable name="vMonth" select=
"substring-before(substring-after($vdatePart, '.'), '.')"/>
<xsl:variable name="vDay" select="substring-before(., '.')"/>
<xsl:variable name="vFormattedMonth" select=
"if(string-length($vMonth) eq 1)
then concat('0', $vMonth)
else $vMonth
"/>
<xsl:variable name="vFormattedDay" select=
"if(string-length($vDay) eq 1)
then concat('0', $vDay)
else $vDay
"/>
<xsl:value-of select=
"concat($vYear,
'-',
$vFormattedMonth,
'-',
$vFormattedDay,
'T',
substring-after(., ' ')
)"/>
</xsl:template>
</xsl:stylesheet>
在提供的跟踪日志XML文档上执行:
<items>
<item>
<date>14.7.2012 11:08:07.222</date>
<MyPosition> // Position data </MyPosition>
</item>
<item>
<date>14.7.2012 12:13:07.112</date>
<MyPosition> // Position data </MyPosition>
</item>
</items>
根据需要合并两个日志:
<item>
<date>2012-07-14T11:08:07</date>
<m:Message xmlns:m="some:M" type="received"> // some content of the message
</m:Message>
</item>
<item>
<date>2012-07-14T11:08:07.222</date>
<MyPosition> // Position data </MyPosition>
</item>
<item>
<date>2012-07-14T11:08:09</date>
<m:Message xmlns:m="some:M" type="received"> // some content of the message2
</m:Message>
</item>
<item>
<date>2012-07-14T12:13:07.112</date>
<MyPosition> // Position data </MyPosition>
</item>
注意:在实际情况下,将使用document()
函数获取消息日志。