我有这个XML,我想有一个CSV格式:我使用python和lxml.etree库
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RsuProtocol schemaVersion="1.11" RefSchemaFile="xxxx.xsd">
<UpdateStep>
<Phase>x1Activation</Phase>
<TimestampStart>1687771672000</TimestampStart>
<TimestampEnd>1687771828000</TimestampEnd>
</UpdateStep>
<UpdateStep>
<Phase>x2Execution</Phase>
<TimestampStart>1687771828000</TimestampStart>
<TimestampEnd>1687771907000</TimestampEnd>
<Warning>
<WarnCode>0x00000000</WarnCode>
<Count>2</Count>
<FirstOccurrence>1687771907</FirstOccurrence>
<SpecificWarnCode>blablabla</SpecificWarnCode>
<WarnMessage>Hello</WarnMessage>
</Warning>
<Warning>
<WarnCode>0x11111111</WarnCode>
<Count>1</Count>
<FirstOccurrence>1687771907</FirstOccurrence>
<SpecificWarnCode>helo</SpecificWarnCode>
<WarnMessage>Hello</WarnMessage>
</Warning>
</UpdateStep>
<UpdateStep>
<Phase>x3MguCompletion</Phase>
<TimestampStart>1687771907000</TimestampStart>
<TimestampEnd>1687771965000</TimestampEnd>
</UpdateStep>
</RsuProtocol>
我希望有这样的输出:
"1","x1Activation","","2023-06-26 09:27:52.000000000","2023-06-26 09:30:28.000000000","","","","",""
"2","x2Execution","","2023-06-26 09:30:28.000000000","2023-06-26 09:31:47.000000000","0x00000000","2","2023-06-26 09:31:47.000000000","blablabla","Hello"
"3","x2Execution","","2023-06-26 09:30:28.000000000","2023-06-26 09:31:47.000000000","0x11111111","1","2023-06-26 09:31:47.000000000","helo","Hello"
"4","x3Completion","","2023-06-26 09:31:47.000000000","2023-06-26 09:32:45.000000000","","","","",""
我有这样的输出:
"1","x1Activation","","2023-06-26 09:27:52.000000000","2023-06-26 09:30:28.000000000","","","","",""
"2","x2Execution","","2023-06-26 09:30:28.000000000","2023-06-26 09:31:47.000000000","0x00000000","2","2023-06-26 09:31:47.000000000","blablabla","Hello"
"3","x3Completion","","2023-06-26 09:31:47.000000000","2023-06-26 09:32:45.000000000","","","","",""
对于我使用的xslt,我只获得Phase= 'x2Execution'的一行,我想获得两个“warning”信息,每个“warning”信息用于阶段的每一行。
这是我使用的xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/RsuProtocol" name="FBM_UPDATE">
<xsl:for-each select="UpdateStep">
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="position()"/>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="Phase"/>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="DiagnosisAddress"/>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data">
<xsl:call-template name="get-datetime-from-timestamp">
<xsl:with-param name="timestamp">
<xsl:call-template name="convert-to-null">
<xsl:with-param name="input" select="TimestampStart"/>
<xsl:with-param name="value" select="'-1'"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data">
<xsl:call-template name="get-datetime-from-timestamp">
<xsl:with-param name="timestamp">
<xsl:call-template name="convert-to-null">
<xsl:with-param name="input" select="TimestampEnd"/>
<xsl:with-param name="value" select="'-1'"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="Warning/WarnCode"/>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="Warning/Count"/>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data">
<xsl:call-template name="get-datetime-from-timestamp">
<xsl:with-param name="timestamp">
<xsl:call-template name="convert-to-null">
<xsl:with-param name="input" select="Warning/FirstOccurrence"/>
<xsl:with-param name="value" select="'-1'"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="Warning/SpecificWarnCode"/>
</xsl:call-template>
<xsl:call-template name="format-csv-field">
<xsl:with-param name="data" select="Warning/WarnMessage"/>
<xsl:with-param name="no-delim" select="'true'"/>
</xsl:call-template>
<xsl:value-of select="$new-line"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
1条答案
按热度按时间sh7euo9m1#
您发布的样式表抛出错误,因为命名模板丢失。
尽管如此,我认为实际问题已经足够清楚了,所以这里有一个简化的例子,你可以用它作为你的起点:
XSLT 1.0
应用于输入XML示例,这将产生:
结果
或者,您可以在2个过程中进行转换:首先,通过使每个警告成为一个完整的步骤,包含来自父步骤的所有数据,来“扁平化”输入;然后统一处理结果,为每一步创建一行。