【发布时间】:2022-12-18 20:35:49
【问题描述】:
我正在尝试使用 XPath 3.0 (xidel --xpath) 将以下 XML 转换为 CSV:
<?xml version="1.0" encoding="utf-8" ?>
<csv>
<record>
<field1>A</field1>
<field2>B</field2>
<field3>C</field3>
</record>
<record>
<field2> </field2>
<field3></field3>
</record>
<record>
<field1>,,</field1>
<field2>""</field2>
<field3>..</field3>
<field3>.
.</field3>
</record>
</csv>
我的预期输出是:
field1,field2,field3
A,B,C
, ,""
",,","""""",".
."
我遇到了一些问题(第一个不是xidel 特有的):
-
我用distinct-values(/csv/record/*/name())得到字段名称;如何使用该序列提取记录中的数据? -
我想区分一个丢失的和空的字段,但是
xidel的text()选择器似乎并不关心这个;它是 XPath 功能还是xidel错误? -
我不能让return工作;xidel使用不同的语法吗?更新
我自己解决了#1,@ConalTuohy 在他的评论中解决了#2。
这是我现在得到的:
#!/bin/bash IFS='' read -r -d '' xpath <<'EOF' let $csv-escape-string := function($str as xs:string) as xs:string { if ( matches( $str, ',|"|\n' ) ) then concat('"',replace($str,'"','""'),'"') else $str }, $fields-names := distinct-values(/csv/record/*/name()), $csv := ( string-join( $fields-names, ',' ), /csv/record/string-join( ( for $fn in $fields-names return $csv-escape-string(string( *[name()=$fn][last()]/text() )) ), ',' ) ) return $csv EOF xidel --xpath "$xpath" file.xml但是输出不是我想要的:
field1,field2,field3 A,B,C ,, ",,","""""",". ."有人可以尝试使用其他 XPath-3 处理器来确保它是
xidel正在规范化text()吗?
【问题讨论】:
-
我不知道 xidel,但您的 XPath 表达式应该以
let关键字开头以进行这些变量赋值,并以return语句结尾。 -
@ConalTuohy 我更新了我的代码;您手边有用于试用的 XPath-3 处理器吗?