XSLT 转换 XML-to-CSV 访问具有相同名称的嵌套元素
XSLT transformation XML-to-CSV accessing nested elements with same name
我正在尝试将下面的 XML 示例转换为 CSV,但我很难匹配具有相同名称(规则)的嵌套元素。
可以生成此结构的 XSLT 转换是什么?
文件@路径="filename1.txt" |规则@id="3.1.6" |消息@严重性=“3” | Message@text="3480. ....."
文件@路径="filename1.txt" |规则@id="3.5.19" |消息@严重性=“3” | Message@text="1281. ....."
文件@路径="filename2.txt" |规则@id="3.1.6" |消息@严重性=“3” | Message@text="3480. ....."
文件@路径="filename2.txt" |规则@id="3.5.3" |消息@严重性=“3” | Message@text="3219. ....."
路径看起来像:
AnalysisData\dataroot type="per-file"\File\tree type="rules"\RuleGroup name="MISRA_C"\...\Rule id="[1-9]+\.[1-9]+\.[1-9]+"\Message
输入XML是:
<AnalysisData>
<dataroot type="project">
</dataroot>
<dataroot type="per-file">
<File path="filename1.txt">
<Json>1.json</Json>
<tree type="rules">
<RuleGroup name="MISRA_C" total="2" active="2" >
<Rule id="3" total="2" active="2" text="Mandatory" >
<Rule id="3.1" total="1" active="1" text="Common" >
<Rule id="3.1.6" total="1" active="1" text="Declarations and definitions" >
<Message guid="qac-9.6.0-3480" total="1" active="1" severity="3" text="3480. Object/function '%s', with internal linkage, has been defined in a header file." />
</Rule>
</Rule>
<Rule id="3.5" total="1" active="1" text="MISRA Required Rules" >
<Rule id="3.5.19" total="1" active="1" text="M3CM Rule-7.2 A "u" or "U" suffix shall be applied to all integer constants that are represented in an unsigned type" >
<Message guid="qac-9.6.0-1281" total="1" active="1" severity="3" text="1281. Integer literal constant is of an unsigned type but does not include a "U" suffix." />
</Rule>
</Rule>
</Rule>
</RuleGroup>
</tree>
</File>
<File path="filename2.txt">
<Json>2.json</Json>
<tree type="rules">
<RuleGroup name="CrossModuleAnalysis" total="11" active="11" >
<Rule id="1" total="11" active="11" text="Maintainability" >
<Rule id="1.1" total="11" active="11" text="CMA Declaration Standards" >
<Message guid="rcma-2.0.0-1534" total="11" active="11" severity="2" text="1534. The macro '%1s' is declared but not used within this project." />
</Rule>
</Rule>
</RuleGroup>
<RuleGroup name="MISRA_C" total="36" active="16" >
<Rule id="3" total="20" active="0" text="Mandatory" >
<Rule id="3.1" total="12" active="0" text="Common" >
<Rule id="3.1.6" total="12" active="0" text="Declarations and definitions" >
<Message guid="qac-9.6.0-3480" total="12" active="0" severity="3" text="3480. Object/function '%s', with internal linkage, has been defined in a header file." />
</Rule>
</Rule>
<Rule id="3.5" total="8" active="0" text="MISRA Required Rules" >
<Rule id="3.5.3" total="8" active="0" text="M3CM Rule-2.1 A project shall not contain unreachable code" >
<Message guid="qac-9.6.0-3219" total="8" active="0" severity="3" text="3219. Static function '%s()' is not used within this translation unit." />
</Rule>
</Rule>
</Rule>
<Rule id="2" total="16" active="16" text="Minor" >
<Rule id="2.1" total="16" active="16" text="Common" >
<Rule id="2.1.15" total="16" active="16" text="Declarations and Definitions" >
<Message guid="qac-9.6.0-3227" total="16" active="16" severity="2" text="3227. The parameter '%s' is never modified and so it could be declared with the 'const' qualifier." />
</Rule>
</Rule>
</Rule>
</RuleGroup>
</tree>
</File>
</dataroot>
</AnalysisData>
我通常建议为映射到一行的元素编写一个模板,然后使用 xsl:value-of separator
输出带有您选择的分隔符的行:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="text"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:apply-templates
select="/AnalysisData/dataroot[@type = 'per-file']/File/tree/RuleGroup[@name = 'MISRA_C']//Rule[Message]"/>
</xsl:template>
<xsl:template match="Rule">
<xsl:value-of select="ancestor::File/@path, @id, Message!(@severity, @text)" separator=" | "/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
如果您想输出属性值加上 element/attribute 名称,那么一个函数可能会有所帮助:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="text"/>
<xsl:function name="mf:line" as="xs:string*">
<xsl:param name="atts" as="attribute()*"/>
<xsl:sequence
select="$atts ! (local-name(..) || '@' || local-name() || '="' || . || '"')"/>
</xsl:function>
<xsl:template match="/" name="xsl:initial-template">
<xsl:apply-templates
select="/AnalysisData/dataroot[@type = 'per-file']/File/tree/RuleGroup[@name = 'MISRA_C']//Rule[Message]"/>
</xsl:template>
<xsl:template match="Rule">
<xsl:value-of select="mf:line((ancestor::File/@path, @id, Message!(@severity, @text)))" separator=" | "/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
我正在尝试将下面的 XML 示例转换为 CSV,但我很难匹配具有相同名称(规则)的嵌套元素。
可以生成此结构的 XSLT 转换是什么?
文件@路径="filename1.txt" |规则@id="3.1.6" |消息@严重性=“3” | Message@text="3480. ....."
文件@路径="filename1.txt" |规则@id="3.5.19" |消息@严重性=“3” | Message@text="1281. ....."
文件@路径="filename2.txt" |规则@id="3.1.6" |消息@严重性=“3” | Message@text="3480. ....."
文件@路径="filename2.txt" |规则@id="3.5.3" |消息@严重性=“3” | Message@text="3219. ....."
路径看起来像:
AnalysisData\dataroot type="per-file"\File\tree type="rules"\RuleGroup name="MISRA_C"\...\Rule id="[1-9]+\.[1-9]+\.[1-9]+"\Message
输入XML是:
<AnalysisData>
<dataroot type="project">
</dataroot>
<dataroot type="per-file">
<File path="filename1.txt">
<Json>1.json</Json>
<tree type="rules">
<RuleGroup name="MISRA_C" total="2" active="2" >
<Rule id="3" total="2" active="2" text="Mandatory" >
<Rule id="3.1" total="1" active="1" text="Common" >
<Rule id="3.1.6" total="1" active="1" text="Declarations and definitions" >
<Message guid="qac-9.6.0-3480" total="1" active="1" severity="3" text="3480. Object/function '%s', with internal linkage, has been defined in a header file." />
</Rule>
</Rule>
<Rule id="3.5" total="1" active="1" text="MISRA Required Rules" >
<Rule id="3.5.19" total="1" active="1" text="M3CM Rule-7.2 A "u" or "U" suffix shall be applied to all integer constants that are represented in an unsigned type" >
<Message guid="qac-9.6.0-1281" total="1" active="1" severity="3" text="1281. Integer literal constant is of an unsigned type but does not include a "U" suffix." />
</Rule>
</Rule>
</Rule>
</RuleGroup>
</tree>
</File>
<File path="filename2.txt">
<Json>2.json</Json>
<tree type="rules">
<RuleGroup name="CrossModuleAnalysis" total="11" active="11" >
<Rule id="1" total="11" active="11" text="Maintainability" >
<Rule id="1.1" total="11" active="11" text="CMA Declaration Standards" >
<Message guid="rcma-2.0.0-1534" total="11" active="11" severity="2" text="1534. The macro '%1s' is declared but not used within this project." />
</Rule>
</Rule>
</RuleGroup>
<RuleGroup name="MISRA_C" total="36" active="16" >
<Rule id="3" total="20" active="0" text="Mandatory" >
<Rule id="3.1" total="12" active="0" text="Common" >
<Rule id="3.1.6" total="12" active="0" text="Declarations and definitions" >
<Message guid="qac-9.6.0-3480" total="12" active="0" severity="3" text="3480. Object/function '%s', with internal linkage, has been defined in a header file." />
</Rule>
</Rule>
<Rule id="3.5" total="8" active="0" text="MISRA Required Rules" >
<Rule id="3.5.3" total="8" active="0" text="M3CM Rule-2.1 A project shall not contain unreachable code" >
<Message guid="qac-9.6.0-3219" total="8" active="0" severity="3" text="3219. Static function '%s()' is not used within this translation unit." />
</Rule>
</Rule>
</Rule>
<Rule id="2" total="16" active="16" text="Minor" >
<Rule id="2.1" total="16" active="16" text="Common" >
<Rule id="2.1.15" total="16" active="16" text="Declarations and Definitions" >
<Message guid="qac-9.6.0-3227" total="16" active="16" severity="2" text="3227. The parameter '%s' is never modified and so it could be declared with the 'const' qualifier." />
</Rule>
</Rule>
</Rule>
</RuleGroup>
</tree>
</File>
</dataroot>
</AnalysisData>
我通常建议为映射到一行的元素编写一个模板,然后使用 xsl:value-of separator
输出带有您选择的分隔符的行:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="text"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:apply-templates
select="/AnalysisData/dataroot[@type = 'per-file']/File/tree/RuleGroup[@name = 'MISRA_C']//Rule[Message]"/>
</xsl:template>
<xsl:template match="Rule">
<xsl:value-of select="ancestor::File/@path, @id, Message!(@severity, @text)" separator=" | "/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
如果您想输出属性值加上 element/attribute 名称,那么一个函数可能会有所帮助:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="text"/>
<xsl:function name="mf:line" as="xs:string*">
<xsl:param name="atts" as="attribute()*"/>
<xsl:sequence
select="$atts ! (local-name(..) || '@' || local-name() || '="' || . || '"')"/>
</xsl:function>
<xsl:template match="/" name="xsl:initial-template">
<xsl:apply-templates
select="/AnalysisData/dataroot[@type = 'per-file']/File/tree/RuleGroup[@name = 'MISRA_C']//Rule[Message]"/>
</xsl:template>
<xsl:template match="Rule">
<xsl:value-of select="mf:line((ancestor::File/@path, @id, Message!(@severity, @text)))" separator=" | "/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>