【问题标题】:Processing XML into MySQL in good form以良好的形式将 XML 处理成 MySQL
【发布时间】:2009-03-30 15:38:06
【问题描述】:

我需要每天将不同格式的 XML 文档处理成 MySQL 数据库中的记录。我需要的每个 XML 文档中的数据都散布着大量我不需要的数据,而且每个文档的节点名称都不同。例如:

来源#1:

<object id="1">
    <title>URL 1</title>
    <url>http://www.one.com</url>
    <frequency interval="60" />
    <uselessdata>blah</uselessdata>
</object>
<object id="2">
    <title>URL 2</title>
    <url>http://www.two.com</url>
    <frequency interval="60" />
    <uselessdata>blah</uselessdata>
</object>

来源#2:

<object">
    <objectid>1</objectid>
    <thetitle>URL 1</thetitle>
    <link>http://www.one.com</link>
    <frequency interval="60" />
   <moreuselessdata>blah</moreuselessdata>
</object>
<object">
    <objectid>2</objectid>
    <thetitle>URL 2</thetitle>
    <link>http://www.two.com</link>
    <frequency interval="60" />
    <moreuselessdata>blah</moreuselessdata>
</object>

...我需要对象的 ID、间隔和 URL。

我对方法的想法是:

1.) 有一个单独的函数来解析每个 XML 文档并从该函数中迭代地创建 SQL 查询

2.) 有一个单独的函数解析每个文档并迭代地将每个对象添加到我自己的对象类中,并通过类方法完成 SQL 工作

3.) 使用 XSLT 将所有文档转换为通用 XML 格式,然后为该文档编写解析器。

XML 文档本身并没有那么大,因为大多数都小于 1MB。我预计它们的结构不会经常变化(如果有的话),但随着时间的推移,我很有可能需要添加和删除更多来源。我对所有想法持开放态度。

另外,很抱歉,如果上面的 XML 示例被破坏了......它们并不是非常重要,只是一个粗略的想法,表明每个文档中的节点名称是不同的。

【问题讨论】:

    标签: python xml xslt parsing


    【解决方案1】:

    使用 XSLT 太过分了。我喜欢方法(2),它很有意义。

    使用 Python,我会尝试为每种文档类型创建一个类。该类将从 dict 继承并在其__init__ 上解析给定的文档并使用“id”、“interval”和“url”填充自身。

    那么 main 中的代码将非常简单,只需使用适当的文档实例化这些类(也是 dicts)的实例,然后将它们作为普通 dicts 传递。

    【讨论】:

    • +1:在您的情况下,不同的 XML 文档实际上只是不同的标签名称。反过来,这些只是更改您在 ElementTree 的 find 和 findall 函数中使用的 XPath 字符串。不同的 XML 解析选项真的很容易做到。
    【解决方案2】:

    我已经成功地使用了变体第三种方法。但我一直在处理的文件要大得多。是否过度杀伤,这真的取决于您对 XSLT 的熟练程度。

    【讨论】:

      【解决方案3】:

      如果你的各种输入格式是明确的,你可以这样做:

      <xsl:template match="object">
        <object>
          <id><xsl:value-of select="@id | objectid" /></id>
          <title><xsl:value-of select="title | thetitle" /></title>
          <url><xsl:value-of select="url | link" /></url>
          <interval><xsl:value-of select="frequency/@interval" /></interval>
        </object>
      </xsl:template>
      

      对于您的示例输入,这会产生:

      <object>
        <id>1</id>
        <title>URL 1</title>
        <url>http://www.one.com</url>
        <interval>60</interval>
      </object>
      <object>
        <id>2</id>
        <title>URL 2</title>
        <url>http://www.two.com</url>
        <interval>60</interval>
      </object>
      <object>
        <id>1</id>
        <title>URL 1</title>
        <url>http://www.one.com</url>
        <interval>60</interval>
      </object>
      <object>
        <id>2</id>
        <title>URL 2</title>
        <url>http://www.two.com</url>
        <interval>60</interval>
      </object>
      

      但是,可能有比使用 XSLT 更快的方法来获得可用的结果。只需衡量每种方法的速度有多快,以及对您的感觉有多“丑陋”。我倾向于说 XSLT 是处理 XML 的更优雅/可维护的解决方案。 YMMV。

      如果您的输入格式不明确并且上述解决方案产生了错误的结果,则需要一种更明确的方法,类似于:

      <xsl:template match="object">
        <object>
          <xsl:choose>
            <xsl:when test="@id and title and url and frequency/@interval">
              <xsl:apply-templates select="." mode="format1" />
            </xsl:when>
            <xsl:when test="objectid and thetitle and link and frequency/@interval">
              <xsl:apply-templates select="." mode="format2" />
            </xsl:when>
          </xsl:choose>
        </object>
      </xsl:template>
      
      <xsl:template match="object" mode="format1">
        <id><xsl:value-of select="@id" /></id>
        <title><xsl:value-of select="title" /></title>
        <url><xsl:value-of select="url" /></url>
        <interval><xsl:value-of select="frequency/@interval" /></interval>
      </xsl:template>
      
      <xsl:template match="object" mode="format2">
        <id><xsl:value-of select="objectid" /></id>
        <title><xsl:value-of select="thetitle" /></title>
        <url><xsl:value-of select="link" /></url>
        <interval><xsl:value-of select="frequency/@interval" /></interval>
      </xsl:template>
      

      【讨论】:

        猜你喜欢
        • 2010-11-08
        • 1970-01-01
        • 1970-01-01
        • 2011-03-22
        • 1970-01-01
        • 2016-11-10
        • 1970-01-01
        • 1970-01-01
        • 2010-09-14
        相关资源
        最近更新 更多