c - Unix XML 文件转换为平面文件

标签 c xml perl parsing unix

我们在 unix 上有多个 xml 文件。我们需要将它们转换成平面文件。我们使用 C 解析了一层 xml 文件(使用 C 是因为 C 可以与 Teradata faSTLoad 通信,这是我们使用 inmod 的目标框,它将在一次解析中完成,否则在其他语言中我们需要进行两次解析一种用于转换为平面文件,另一种用于加载 ito teradata)。即下面的文件

<book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
   </book>

转化为

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~44.95~

这是我们通过在 C 中解析文件来实现的。但是在看到下面的 xml 文件的原始格式之后。 (请不要将其视为必需文件。我只是提供一个想法)

<book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
             <modified>2010-01-02</modified>
             <modified>2010-01-03</modified>
      <price>44.95</price>
   </book>

这似乎应该转换为两条记录。

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02~44.95~
bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-03~44.95~

但是现在我们觉得我们的 C 代码对于这个请求来说会很复杂。所以我们正在寻找可以在 unix 上轻松使用的其他选项。任何人都可以给我们任何适用于 unix 的不同语言/选项的工作示例代码吗?

最佳答案

您可以使用 XSLT。我使用可以在 Unix 上运行的 Saxon (Java)。

此样式表处理您的两个 XML 示例:

<?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"/>
  <xsl:template match="/book">
    <xsl:choose>
      <xsl:when test="modified">
        <xsl:for-each select="modified">
          <xsl:call-template name="dump-line">
            <xsl:with-param name="pos" select="position()"/>
          </xsl:call-template>          
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="@id"/><xsl:text>~</xsl:text>
        <xsl:value-of select="author"/><xsl:text>~</xsl:text>
        <xsl:value-of select="title"/><xsl:text>~</xsl:text>
        <xsl:value-of select="genre"/><xsl:text>~</xsl:text>
        <xsl:value-of select="price"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="dump-line">
    <xsl:param name="pos"/>
    <xsl:value-of select="/book/@id"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/author"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/title"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/genre"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/modified[$pos]"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/price"/>
    <xsl:text>&#x0A;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

如果没有modified元素,则输出一条记录。如果有 modified 元素,它会输出与 modified 元素一样多的记录。

带有修改元素的示例输出:

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02~44.95
bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-03~44.95

关于c - Unix XML 文件转换为平面文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4470467/

相关文章:

PHP 包装每 4 个元素

perl - grep regex 到 perl 或 awk

perl - 以逗号分隔,但仅当不在括号中时

perl - 如何从 Excel 调用 Perl 脚本?

c - 保存当前的阅读位置,以便我以后可以寻找它

c - GTK+ 和 OpenGL

c - 在 clang 中,如何使用每个函数的优化属性?

xml - 大型 XML 文件的体系结构和缓存注意事项

c - 警告 : ‘struct user_data_s’ declared inside parameter list

c# - 读取xml文件时如何处理文件结尾