【问题标题】:how should I go about converting xml into csv我应该如何将 xml 转换为 csv
【发布时间】:2012-11-09 22:38:02
【问题描述】:

我正在尝试获取一些 xml 代码,示例如下:

  <time_report>

 <project_ID>4</project_ID>

 <project_status>close</project_status>

 <client_ID>6001</client_ID>

     <time_record>

            <project_start_time>15:02:33</project_start_time>

            <project_end_time>15:07:44</project_end_time>

            <project_total_time>PT00H05M11S</project_total_time>

     </time_record>

 <employee_ID>10001</employee_ID>

 <employee_name>Mary Beth</employee_name>

 <date_created>2009-08-25</date_created>

</time_report>

然后输出,格式如下:

project_id, project_status, client_id, project_start_time, project_end_time,  project_total_time, employee_ID, employee_name, date_created

4, close, 6001, 15:02:33, 15:07:44, PT00H05M11S, 10001, Mary Beth, 2009-08-25

我一直在尝试使用 xmllint 来执行此操作,但不幸的是无法取得任何进展,我说我想知道是否有人对我应该做什么提出建议?我将在 bash/shell 环境中执行此操作。任何帮助将不胜感激,谢谢!

还忘了提到如果我在excel中打开xml文件然后另存为csv,我可以得到正确的结果,只是在linux中寻找一种方法

    project_ID,project_status,client_ID,project_start_time,project_end_time,project_total_time,employee_ID,employee_name,date_created
4,close,6001,15:02:33,15:07:44,PT00H05M11S,10001,Mary Beth,8/25/2009
5,open,6003,12:00:00,12:45:00,PT00H45M00S,10003,Michelle,9/11/2009
2,close,6002,10:00:00,10:30:00,PT00H30M00S,10002,Joe,8/25/2009
2,open,6004,12:00:00,3:27:05,PT03H23M05S,10004,Mike,8/13/2009

【问题讨论】:

标签: xml bash xml-parsing


【解决方案1】:

xmlstarlet 是一个非常强大的命令行工具,可让您查询 XML 或运行 XSLT 翻译。有一些 XSLT XML->CSV 示例随处可见,但以下单行代码可以满足您的需求:

xmlstarlet sel -B -t -m "//time_reports/time_report" -n -m "*" -v . -o , input.xml

唯一的问题是我需要用一个名为 &lt;time_reports&gt; 的根级标签来包装 &lt;time_report&gt;

【讨论】:

  • 您好,谢谢!我已经继续尝试了,但不幸的是,当我执行命令时,没有输出任何内容。这是文件本身i.minus.com/ixkoCbKj30tXq.png,当我执行 xmlstarlet i.minus.com/ieYnWqj7MLLWY.png 时会发生这种情况,不确定我是否只是犯了一个愚蠢的错误或类似的错误,再次感谢您的帮助!
  • 哦,我实际上能够让它正常工作,感谢您的帮助!
【解决方案2】:

要将您的 XML 转换为 CSV(例如 xsltproc),您可以使用这样的 XSL 样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:for-each select="//time_report[position()=1]/*">
            <xsl:if test="not(position()=1)">
                <xsl:text>,</xsl:text>
            </xsl:if>
            <xsl:value-of select="name()" />
        </xsl:for-each>
        <xsl:text>&#13;</xsl:text>
        <xsl:for-each select="//time_report">
            <xsl:for-each select="./*">
                <xsl:if test="not(position()=1)">
                    <xsl:text>,</xsl:text>
                </xsl:if>
                <xsl:value-of select="normalize-space(.)" />
            </xsl:for-each>
            <xsl:text>&#13;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案3】:

    您也可以使用我的Xidel:(假设您的 xml 中没有空字段)

     xidel /tmp/test.xml -e '//time_report/string-join(.//text()[normalize-space(.)], ", ")'
    

    标准的XPath 2,不用记住不同命令行参数的名字...

    或者没有这个假设:

     xidel /tmp/test.xml -e '//time_report/string-join(.//*[not(*)], ", ")'
    

    【讨论】:

      猜你喜欢
      • 2014-04-23
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 2013-06-20
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多