3

我有一些带有嵌套字段的数据,我想将它们导入 MySQL。可能有很多文件,因此任何可重复的脚本语言都会受到赞赏。看起来这应该比我做的更容易,但我找不到一个好的答案。

我相信最干净的方法是使用连接表,尽管在父表中也存在一个元素会很好,比如在下面的示例中它是否具有类型代码“A1”。

此处回答了一个类似的查询Parsing nested xml into denormalized table,除了那不是 MySQL 并且该数据带有唯一标识符。我的数据面临的挑战之一是数据中没有唯一标识符来创建连接表的主键。

下面的示例数据。在这里,doc-id 和 assignor 标签必须是单独的表并连接起来。数据有一个 DTD,我不包括它的价值。非常感谢任何输入!

 <?xml version="1.0" encoding="UTF-8"?>
<assignment>
    <assignment-record>
        <reel-no>28879</reel-no>
        <frame-no>97</frame-no>
        <last-update-date><date>20120903</date></last-update-date>
        <recorded-date><date>20120830</date></recorded-date>
        <page-count>4</page-count>
        <correspondent>
            <name>LEE, HONG, DEGERMAN, KANG &amp; WAIMEY</name>
            <address-1>660 S. FIGUEROA ST., 23RD FL.</address-1>
            <address-2>LOS ANGELES, CA 90017</address-2>
        </correspondent>
        <conveyance-text>ASSIGNMENT OF ASSIGNORS INTEREST (SEE DOCUMENT FOR DETAILS).</conveyance-text>
    </assignment-record>
    <assignors>
        <assignor>
            <name>WOO, SUNGHO</name>
            <execution-date><date>20120806</date></execution-date>
        </assignor>
            <assignor>
                <name>CHOI, JAEYOUNG</name>
                <execution-date><date>20120806</date></execution-date>
        </assignor>
    </assignors>
    <docproperties>
        <property>
            <document-id>
                <country>US</country>
                <doc-number>13277056</doc-number>
                <kind>X0</kind>
                <date>20111019</date>
            </document-id>
            <document-id>
                <country>US</country>
                <doc-number>20120213136</doc-number>
                <kind>A1</kind>
                <date>20120823</date>
            </document-id>
            <title lang="en">SYSTEMS AND METHODS FOR CONTROLLING SENSOR DEVICES IN MOBILE DEVICES</title>
     </property>
    </docproperties>
</assignment>
</xml>
4

1 回答 1

2

由于这个三年前未回答的问题最近被另一位用户提出,我继续代表社区回答它,因为原来的 OP 不再活跃。

对于未来的读者,只要您需要为平面文件导入(例如数据库表)扁平化嵌套 XML 文件,请考虑XSLT,这是一种用于操作 XML 文件的转换语言。实际上,所有通用语言都有一些用于 XSLT 1.0 处理的库,包括 Python、PHP、Perl、Java、C#、VB 等。

正如 OP 提到的 Python,下面的示例使用第三方lxml模块来展平 XML 文件。为了生成一个唯一的 id 来关联数据<assignor><document-id>数据,运行 XSLT 脚本中的 XPathancestor以检索两个节点作为兄弟共享的reel-no值。<assignment-record>这类似于发布链接中的 TSQL 解决方案。

XSLT脚本(另存为 .xsl 以在 Python 中引用)

转让人转换

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <xsl:template match="/assignment">
    <xsl:copy>      
      <xsl:apply-templates select="descendant::assignor"/>
    </xsl:copy>
  </xsl:template>  

  <xsl:template match="assignor">
    <xsl:copy>
      <assign_id>
          <xsl:value-of select="ancestor::assignment/assignment-record/reel-no"/>
      </assign_id>
      <xsl:copy-of select="name"/>
      <xsl:copy-of select="execution-date/date"/>        
    </xsl:copy>
  </xsl:template>

</xsl:transform>

文档 ID 转换

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <xsl:template match="/assignment">
    <xsl:copy>
      <xsl:apply-templates select="descendant::document-id"/>
    </xsl:copy>
  </xsl:template>  

  <xsl:template match="document-id">
    <xsl:copy>
      <assign_id>
          <xsl:value-of select="ancestor::assignment/assignment-record/reel-no"/>
      </assign_id>
      <xsl:copy-of select="*"/>        
    </xsl:copy>
  </xsl:template>

</xsl:transform>

Python脚本(将源代码转换为两个文件)

import lxml.etree as ET

dom = ET.parse('Assignment.xml')
xslt = ET.parse('Assignor_XSLT_Script.xsl')

transform = ET.XSLT(xslt)
newdom = transform(dom)    

xmlfile = open(os.path.join(cd, 'Assignor.xml'),'wb')
xmlfile.write(newdom)
xmlfile.close()    

xslt = ET.parse('Document-Id_XSLT_Script.xsl')    
transform = ET.XSLT(xslt)
newdom = transform(dom)

xmlfile = open(os.path.join(cd, 'Document-Id.xml'),'wb')
xmlfile.write(newdom)
xmlfile.close()    

XML输出(现在可以有效地使用 MySQL 的 LOAD XML)

<?xml version="1.0" encoding="UTF-8"?>
<assignment>
  <assignor>
    <assign_id>28879</assign_id>
    <name>WOO, SUNGHO</name>
    <date>20120806</date>
  </assignor>
  <assignor>
    <assign_id>28879</assign_id>
    <name>CHOI, JAEYOUNG</name>
    <date>20120806</date>
  </assignor>
</assignment>


<?xml version="1.0" encoding="UTF-8"?>
<assignment>
  <document-id>
    <assign_id>28879</assign_id>
    <country>US</country>
    <doc-number>13277056</doc-number>
    <kind>X0</kind>
    <date>20111019</date>
  </document-id>
  <document-id>
    <assign_id>28879</assign_id>
    <country>US</country>
    <doc-number>20120213136</doc-number>
    <kind>A1</kind>
    <date>20120823</date>
  </document-id>
</assignment>
于 2016-10-06T03:13:23.300 回答