MySQL LOAD XML 在导入时缺少子节点

Posted

技术标签:

【中文标题】MySQL LOAD XML 在导入时缺少子节点【英文标题】:MySQL LOAD XML missing child nodes on import 【发布时间】:2011-12-18 02:29:56 【问题描述】:

我第一次尝试使用 LOAD XML,并且大部分都得到了我想要的结果,因为大部分 XML 数据被传输到数据库表和它们各自的列中,但是有两列是没有正确导入。

让我展示一个典型 XML 结构的示例,以便您了解原因(这显然只是文件中的一条记录)。

注意: XML 结构无法更改,这是从我无法控制的文件中读取的,因此我必须按原样使用该结构。

<trait name="ArmorBldg_R001">
    <dbid>450</dbid>
    <traittype>ArmorBuilding</traittype>
    <rarity>rare</rarity>
    <icon>UserInterface\Icons\Equipment\ArmBuildR3_ua</icon>
    <rollovertextid>53253</rollovertextid>
    <displaynameid>53254</displaynameid>
    <offertype>eOfferCivMatching</offertype>
    <visualfactor type="Body" factor="2.0000"/>
    <sellable>1</sellable>
    <tradeable>1</tradeable>
    <destroyable>1</destroyable>
    <effects>
        <effect type="Data" bonus="true" amount="1.0122" scaling="0.0031" subtype="Armor" visible="true" damagetype="Ranged" relativity="Percent">
            <target type="Player"/>
        </effect>
        <effect type="Data" bonus="true" amount="1.0197" scaling="0.0052" subtype="Damage" visible="true" allactions="1" relativity="Percent">
            <target type="Player"/>
        </effect>
        <effect type="Data" bonus="true" amount="1.0092" scaling="0.0023" subtype="LOS" visible="true" relativity="Percent">
            <target type="Player"/>
        </effect>
    </effects>
</trait>

我正在使用..导入。

LOAD XML LOCAL INFILE 'C:\path\to\xmlfile\example.xml'
INTO TABLE mytable
ROWS IDENTIFIED BY '<trait>';

这是表结构。

CREATE TABLE `traits` ( 
    `name` varchar(40) NOT NULL, 
    `dbid` smallint(5) unsigned NOT NULL, 
    `traittype` varchar(40) NOT NULL, 
    `rarity` varchar(10) NOT NULL, 
    `icon` varchar(100) NOT NULL, 
    `rollovertextid` mediumint(8) unsigned NOT NULL, 
    `displaynameid` mediumint(8) unsigned NOT NULL, 
    `offertype` varchar(20) NOT NULL, 
    `visualfactor` text NOT NULL, 
    `sellable` tinyint(1) NOT NULL, 
    `tradeable` tinyint(1) NOT NULL, 
    `destroyable` tinyint(1) NOT NULL, 
    `effects` text NOT NULL, 
    UNIQUE KEY `dbid` (`dbid`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

所有记录都正确导入,但每条记录的 visualfactoreffects 列都为空。

我一直在阅读以下两页..

http://dev.mysql.com/doc/refman/5.5/en/load-xml.htmlhttp://dev.mysql.com/doc/refman/5.5/en/load-data.html

..但不幸的是,我什至对从哪里开始感到困惑(那些文档真的很少解释自己),任何人都可以提供一些指示吗?即使它只是一个包含合适(且易于理解)示例的网页。

提前感谢任何可以提供指导的人。

【问题讨论】:

【参考方案1】:

根据mysql documentation,“加载xml”不读取子节点。

【讨论】:

我最终使用了一个解析器来处理更复杂的 XML 文件,LOAD XML 可以处理子文件,但方式有限(该函数确实可以处理更好、更深入的示例)。 【参考方案2】:

在将 XML 导入数据库的速度方面,使用 LOAD XML 确实有优势。但是,您必须找到一些短暂的 LOAD XML 解决方法。您可以在此处找到其中两个。

LOAD XML 不会解析像这样的标签...

它只会解析像...这样的标签

标签>

因此,您需要对标签进行字符串替换..

这样就够了……

<?php
    $string = file_get_contents("example.xml");
    $string = str_replace('<visualfactor type="Body" factor="2.0000"/>','<visualfactor type="Body" factor="2.0000"></visualfactor>',$string);
    file_put_contents("example.xml", $string);
?>

查看标签,您会发现 LOAD XML 的另一个限制。您必须成功地将看到 XML 结构的父子关系映射到您的数据库。

标签有子标签。你应该推断这意味着标签中的所有数据都应该进入另一个表。

以下内容不适用于您的情况... 加载 XML 本地 INFILE 'C:\path\to\xmlfile\example.xml' INTO TABLE mychildtable 由 '' 标识的行;

数据似乎在属性中,因此 LOAD XML 不起作用。您将需要解析出字符串并将其插入。这是我想出的......

<?php

    $xml = simplexml_load_file("example.xml");
    #assumming that the parent tag is traits??
    $array  = $xml->traits;

    foreach($array as $h => $info)
        $key = $info->dbid
        $sql = "Insert Into Table `childData` (`key`,`type`,`bonus`,`amount`,`scaling`,`subtype`,`visible`,damagetype`) VALUES ";
        $effectArray  = $xml->effects->effect;
        foreach($effectArray as $i => $effectInfo)
            $data = (array) $effectInfo->attributes();
            $attributes = $data['@attributes']);
            If($i ==0 )
                $sql .= "('$key', '$attributes['type']', '$attributes['bonus']', '$attributes['amount']', '$attributes['scaling']',  '$attributes['subtype']',$attributes['visible'],$attribute['damagetype'] )";
            else
                $sql .= ",('$key', '$attributes['type']', '$attributes['bonus']', '$attributes['amount']', '$attributes['scaling']',  '$attributes['subtype']',$attributes['visible'],$attribute['damagetype'] )";
            
        
    

?>

【讨论】:

【参考方案3】:

地址示例中https://dev.mysql.com/doc/refman/5.5/en/load-xml.html中所述,您可以试试这个

LOAD XML LOCAL INFILE 'C:\path\to\xmlfile\example.xml'
INTO TABLE mytable
ROWS IDENTIFIED BY '<effect>';

只要每个标签名是唯一的并且列名与标签名相对应,它应该可以工作。

【讨论】:

以上是关于MySQL LOAD XML 在导入时缺少子节点的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XML_LOAD() 将 XML 文件导入 MySQL 数据库表;功能

如何将 JSON, Text, XML, CSV 数据文件导入 MySQL

如何将 JSON,Text,XML,CSV 数据文件导入 MySQL

节点子进程事件监听

如何从父 yaml 节点获取完整的 yaml 节点子对象?

节点子进程执行命令失败,错误代码为 1