按ParentFieldName属性分组将XML片段转换为CSV格式的实现方法咨询
没问题,我来帮你搞定这个XML转CSV的需求!这里有两种靠谱的方案——XSLT转换和修正后的xmlstarlet命令,都能完美匹配你的要求:
解决方案:将XML结构转换为指定CSV格式
方法一:使用XSLT转换
你可以编写一个针对性的XSLT样式表,精准提取并格式化你需要的数据。下面是适配你需求的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="text" encoding="UTF-8"/> <!-- 匹配每个Struct类型的Fields节点,作为每行的数据源 --> <xsl:template match="Fields[@FieldType='Struct']"> <!-- 按顺序拼接当前Struct下的四个指定字段值 --> <xsl:value-of select="../Fields[@FieldName=concat(@FieldName, '.class_id')]/@FieldValue"/> <xsl:text>;</xsl:text> <xsl:value-of select="../Fields[@FieldName=concat(@FieldName, '.logical_name')]/@FieldValue"/> <xsl:text>;</xsl:text> <xsl:value-of select="../Fields[@FieldName=concat(@FieldName, '.attribute_index')]/@FieldValue"/> <xsl:text>;</xsl:text> <xsl:value-of select="../Fields[@FieldName=concat(@FieldName, '.data_index')]/@FieldValue"/> <xsl:text> </xsl-text> <!-- 添加换行符分隔行 --> </xsl:template> <!-- 忽略所有无关的文本节点和非目标节点 --> <xsl:template match="text()"/> </xsl:stylesheet>
使用步骤:
- 将上述代码保存为
transform.xsl文件 - 用支持XSLT 1.0的工具(比如
xsltproc或Saxon)执行转换,假设你的XML源文件是input.xml:
xsltproc transform.xsl input.xml > output.csv
逻辑说明:
- 先定位所有标记为
FieldType="Struct"的Fields节点(也就是你示例中PL1.CO.0.0、PL1.CO.0.1这类节点) - 针对每个Struct节点,自动拼接它下属的四个指定字段(class_id、logical_name等)的
FieldValue,用分号分隔 - 自动过滤无关节点,只输出符合要求的行
方法二:使用xmlstarlet(修正后的命令)
你之前用xmlstarlet没成功,大概率是XPath表达式写得不对。试试下面的命令,它会直接输出你要的CSV格式:
xmlstarlet sel -t -m "//Fields[@FieldType='Struct']" \ -v "../Fields[@FieldName=concat(current()/@FieldName, '.class_id')]/@FieldValue" -o ";" \ -v "../Fields[@FieldName=concat(current()/@FieldName, '.logical_name')]/@FieldValue" -o ";" \ -v "../Fields[@FieldName=concat(current()/@FieldName, '.attribute_index')]/@FieldValue" -o ";" \ -v "../Fields[@FieldName=concat(current()/@FieldName, '.data_index')]/@FieldValue" -n \ input.xml
命令解释:
-m "//Fields[@FieldType='Struct']":遍历所有Struct类型的Fields节点-v ...:提取指定字段的FieldValue属性值-o ";":输出分号作为字段分隔符-n:输出换行符分隔每行
用你提供的示例XML测试,两种方法都会输出你预期的结果:
8;000000000000;2;0 1;CAFEBABE0666;2;0 3;FFFFFFFFFFFF;2;0
内容的提问来源于stack exchange,提问作者Mariusz Jędrzejewski
相关产品推荐
相关产品推荐

