【问题标题】:Converting XML to CSV with xmlstarlet with no success使用 xmlstarlet 将 XML 转换为 CSV 没有成功
【发布时间】:2020-03-15 22:31:20
【问题描述】:

我有一个格式如下的 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<appname version="2.3">
  <system name="web host">
    <username><![CDATA[username1]]></username>
    <password><![CDATA[password1]]></password>
    <note><![CDATA[]]></note>
    <url><![CDATA[]]></url>
  </system>
  <system name="vendor name">
    <username><![CDATA[username@email.com]]></username>
    <password><![CDATA[password2]]></password>
    <note><![CDATA[]]></note>
    <url><![CDATA[]]></url>
  </system>
  <system name="vendor name 3">
    <username><![CDATA[username@email.com]]></username>
    <password><![CDATA[password3]]></password>
    <note><![CDATA[]]></note>
    <url><![CDATA[]]></url>
  </system>
<appname>

我正在尝试使用:

xmlstarlet \
  sel -T -t -m /root/system \
  -v "concat(@name,',',username,',',password,',',note,',',url)" \
  -n filename.xml

我得到:

failed to load external entity "concat(@name,',',username,',',password,',',note,',',url)-n"

我只想要当前文档中的制表符分隔文档,以便将其导入另一个密码管理器。我有数百个条目,我真的不想重新输入。

谁能帮忙?

【问题讨论】:

  • 该错误听起来像是引用问题。你在什么上运行 xmlstarlet?如果我将 /root 更改为 /appname (并修复 appname 结束标记),您的命令行对我在 cygwin 中使用 bash 有效。
  • 我在 Mac OS 13 上将它与 Brew 一起使用。

标签: xml csv xmlstarlet


【解决方案1】:

使用 Xidel:

xidel -s vendor.xml -e "/appname/system/join((./@name, ./username/text(), ./password/text()), x:cps(9))"

生产:

web host        username1       password1
vendor name     username@email.com      password2
vendor name 3   username@email.com      password3

感谢 @Reino 提供打印 TAB 字符和 arg 位置的技巧。在 cmd.exe 和 Cygwin bash 上测试引号。

【讨论】:

  • XPath:-e '//system/join((@name,username,password),x:cps(9))'。 XQuery:--xquery '//system/join((@name,username,password),"&amp;#9;")'--printed-node-format=text 不是必需的,因为无论如何它都是默认值。还请将输入 'vendor.xml' 放在提取查询的前面。最后请注意引号。 OP 正在使用需要 Unix 引用的 Mac OS。
【解决方案2】:

冗长而复杂的答案是您需要使用类似的东西

xml sel -T \
  -t -m '//system' \
     -v '@name' \
     -o ' ' \
     -v './username' \
     -o ' ' \
     -v './password' \
     -o ' ' \
     -v './note' \
     -o ' ' \
     -v './url' \
-n file.xml

根据您的 xml 输出:

web host  username1 password1  
vendor name  username@email.com password2  
vendor name 3  username@email.com password3 

更短(更好,恕我直言)的答案是使用更高级的东西,比如 xidel。

【讨论】:

  • 不需要./(即在-v './username'前面),你也可以使用-v 'username',即使用户名周围的引号也不需要。
  • @JackFleeting 使用 Xidel 执行此操作(类似)时遇到问题。能举个例子吗?
猜你喜欢
  • 1970-01-01
  • 2019-03-31
  • 2019-02-02
  • 2017-05-23
  • 2011-10-28
  • 2017-12-14
  • 2012-12-18
相关资源
最近更新 更多