Python 以良好的形式将XML处理成MySQL

Python 以良好的形式将XML处理成MySQL,python,xml,xslt,parsing,Python,Xml,Xslt,Parsing,我需要每天将不同格式的XML文档处理成MySQL数据库中的记录。我从每个XML文档中需要的数据中夹杂着大量我不需要的数据,并且每个文档的节点名称都不同。例如: 资料来源#1: URL 1 http://www.one.com 废话 URL 2 http://www.two.com 废话 资料来源#2: 2. URL 2 http://www.two.com 废话 …其中我需要对象的ID、间隔和URL 我对方法的想法是: 1.)有一个单独的函数来解析每个XML文档,并从该函数中迭代创建SQ

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

资料来源#1:


URL 1
http://www.one.com
废话
URL 2
http://www.two.com
废话
资料来源#2:


2.
URL 2
http://www.two.com
废话
…其中我需要对象的ID、间隔和URL

我对方法的想法是:

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

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

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

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


另外,如果上面的XML示例已损坏,则很抱歉。。。它们并不十分重要,只是一个粗略的想法,表明每个文档中的节点名称是不同的。

使用XSLT是一种过火的做法。我喜欢方法(2),它很有意义

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


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

我已经成功地使用了variant第三种方法。但我处理的文件要大得多。如果这是一种过分的技巧,那么这实际上取决于您对XSLT的熟练程度。

如果您的各种输入格式都是明确的,那么您可以这样做:

<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>

1.
URL 1
http://www.one.com
60
2.
URL 2
http://www.two.com
60
1.
URL 1
http://www.one.com
60
2.
URL 2
http://www.two.com
60
但是,可能有比使用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>

+1:在您的例子中,不同的XML文档实际上只是不同的标记名。反过来,这些函数只需更改在ElementTree find和findall函数中使用的XPath字符串。不同的XML解析选项非常容易实现。
<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>
<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>