【问题标题】:MYSQL - LOAD XML multiple repeating (deplicate) tags as one stringMYSQL - 将 XML 多个重复(重复)标签作为一个字符串加载
【发布时间】:2016-11-11 16:11:47
【问题描述】:

将带有数据的多个重复标签“<image></image>”加载到一个<images> 表格单元格时出现问题。

XML

<posts>
   <item>
      <id>1</id>
      <type>post</type>
      <url>www.url.com/1</url>
      <date>2016-06-15</date>
      <image>some url/1xxx.jpg</image>
      <image>some url/1yyy.jpg</image>
      <image>some url/1zzz.jpg</image>
   </item>
   <item>
      <id>2</id>
      <type>post</type>
      <url>www.url.com/2</url>
      <date>2016-06-12</date>
      <image>some url/2xxx.jpg</image>
      <image>some url/2yyy.jpg</image>
      <image>some url/2zzz.jpg</image>
      <image>some url/2www.jpg</image>
   </item>
   <item>
      <id>3</id>
      <type>post</type>
      <url>www.url.com/3</url>
      <date>2016-06-12</date>
      <image>some url/3fff.jpg</image>
   </item>
</posts>

代码

现在它只加载来自&lt;item&gt; 的最后一个&lt;image&gt; 标记

LOAD XML local infile 'D:\\demo.xml' 
REPLACE 
INTO TABLE posts CHARACTER SET UTF8
ROWS IDENTIFIED BY '<item>'
(@id, @type, @url, @date, @image)
SET id=@id, type=@type, url=@url, date = str_to_date(@date, '%Y-%m'), images=@image;

如何将所有重复的 &lt;image&gt; 标签存储为图像 VARCHAR 或 TEXT

【问题讨论】:

  • 这很公平,因为您只有一个图像列,但您有多个图像!您的原始数据未标准化。所以这会很棘手

标签: mysql sql xml load


【解决方案1】:

考虑使用XSLT 转换您的XML 以将item 和images 标准化为一对多表。下面使用 PHP 运行 XSLT,但大多数通用语言都可以运行 XSLT 1.0 脚本,包括 PHP、Perl、Python、Java、C#、VB。具体来说,转换会将&lt;image&gt;标签从&lt;item&gt;中分离出来,保留对应的&lt;id&gt;,并维护两组标签以上传到两个MySQL数据库表。

XSLT 脚本(另存为 .xsl 文件)

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

  <xsl:template match="/posts">
    <xsl:copy>
      <xsl:apply-templates select="item"/>
      <xsl:apply-templates select="item/image"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item">
    <xsl:copy>
      <xsl:copy-of select="*[local-name()!='image']"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item/image">
    <images>
      <itemid><xsl:value-of select="ancestor::item/id"/></itemid>
      <xsl:copy-of select="."/>
    </images>
  </xsl:template>

</xsl:stylesheet>

PHP脚本

<?php

$cd = dirname(__FILE__);

// LOAD XML AND XSL FILES
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('Original.xml');

$xslfile = new DOMDocument('1.0', 'UTF-8');
$xslfile->load('XSLT_Script.xsl');

// TRANSFORM XML with XSLT
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslfile); 
$newXml = $proc->transformToXML($xml);

// SAVE TO FILE
file_put_contents('Output.xml', $newXml);

?>

输出 (图片包含项目ID)

<?xml version="1.0"?>
<posts>
  <item>
    <id>1</id>
    <type>post</type>
    <url>www.url.com/1</url>
    <date>2016-06-15</date>
  </item>
  <item>
    <id>2</id>
    <type>post</type>
    <url>www.url.com/2</url>
    <date>2016-06-12</date>
  </item>
  <item>
    <id>3</id>
    <type>post</type>
    <url>www.url.com/3</url>
    <date>2016-06-12</date>
  </item>
  <images>
    <itemid>1</itemid>
    <image>some url/1xxx.jpg</image>
  </images>
  <images>
    <itemid>1</itemid>
    <image>some url/1yyy.jpg</image>
  </images>
  <images>
    <itemid>1</itemid>
    <image>some url/1zzz.jpg</image>
  </images>
  <images>
    <itemid>2</itemid>
    <image>some url/2xxx.jpg</image>
  </images>
  <images>
    <itemid>2</itemid>
    <image>some url/2yyy.jpg</image>
  </images>
  <images>
    <itemid>2</itemid>
    <image>some url/2zzz.jpg</image>
  </images>
  <images>
    <itemid>2</itemid>
    <image>some url/2www.jpg</image>
  </images>
  <images>
    <itemid>3</itemid>
    <image>some url/3fff.jpg</image>
  </images>
</posts>

SQL (要上传两个表)

-- POSTS TABLE
LOAD XML local infile 'C:\\Path\\To\\Output.xml' 
REPLACE 
INTO TABLE posts CHARACTER SET UTF8
ROWS IDENTIFIED BY '<item>'
(@id, @type, @url, @date)
SET id=@id, type=@type, url=@url, date=str_to_date(@date, '%Y-%m');

-- IMAGES TABLE    
LOAD XML local infile 'C:\\Path\\To\\Output.xml' 
REPLACE 
INTO TABLE images CHARACTER SET UTF8
ROWS IDENTIFIED BY '<images>'
(@itemid, @image)
SET itemid=@itemid, image=@image;

【讨论】:

  • 谢谢冻糕,很棒的帖子。有用。但是我在使用 XSLT 时遇到了另一个问题,我的 XML 文件最大为 1 GB。我将文件切成 50 倍,但仍然出现“内存分配失败”(但对于小文件,它就像一个魅力。
  • 是的,XSLT 在较小的文件上效果很好,但在处理较大的文件时会占用内存,因为它会在处理之前读取整个文档。一些 XSLT 2.0 和 3.0 具有流处理,但这些需要外部扩展。考虑对较大的文件进行切片并使用 PHP 循环导入 MySQL。
  • 通常情况下,您需要一个与 XSLT 文件大小相同的 RAM about 5 times。
猜你喜欢
  • 1970-01-01
  • 2020-03-14
  • 2012-03-31
  • 2019-04-16
  • 1970-01-01
  • 2021-09-24
  • 2012-08-28
  • 2019-12-15
  • 2023-04-05
相关资源
最近更新 更多