Как использовать этот код Coldfusion для чтения большого файла XML и вставки данных в базу данных? - PullRequest
1 голос
/ 14 октября 2011

Я использую ColdFusion (openBlueDragon) для вставки данных из большого (200 МБ) XML-файла в базу данных без необходимости загружать весь файл в память, как я обычно это делал. Я нашел ОЧЕНЬ ПОДОБНЫЙ ВОПРОС здесь: Цикл по большому XML-файлу , который, кажется, является ответом, который я ищу.

Однако я не достаточно опытен в Java, чтобы понимать и адаптировать код под мои нужды. Я не нашел способа ответить эксперту (@orangepips), который разместил код, иначе я бы не стал публиковать подобный вопрос.

Мой xml-файл выглядит так:

 <allItems>
    <item>
        <subject>The subject text</subject>
        <date>2007-05-21 04:03:00</date>
        <content>text content often contains many paragraphs of text</content>
        <author>JPass78</author> 
    </item>
</allItems>

Это код, любезно предоставленные апельсины, которые я пытаюсь адаптировать для своих целей. Я немного изменил это, чтобы включить мои собственные имена полей:

<cfset fis = createObject("java", "java.io.FileInputStream").init(
"#getDirectoryFromPath(getCurrentTemplatePath())#/file.xml")>
<cfset bis = createObject("java", "java.io.BufferedInputStream").init(fis)>
<cfset XMLInputFactory = createObject("java", "javax.xml.stream.XMLInputFactory").newInstance()>
<cfset reader = XMLInputFactory.createXMLStreamReader(bis)>

<cfloop condition="#reader.hasNext()#">
<cfset event = reader.next()>
<cfif event EQ reader.START_ELEMENT>
    <cfswitch expression="#reader.getLocalName()#">
        <cfcase value="allItems">
            <!--- root node, do nothing --->
        </cfcase>
        <cfcase value="item">
            <!--- set values used later on for inserts, selects, updates --->
        </cfcase>
        <cfcase value="subject">
            <!--- some selects and insert --->
        </cfcase>
        <cfcase value="contentdate">
            <!--- insert or update --->
        </cfcase>
        <cfcase value="content">
        </cfcase>
        <cfcase value="author">
         </cfcase>  
    </cfswitch>
</cfif>
</cfloop>
<cfset reader.close()>

У меня есть одна таблица, и я пытаюсь выяснить, как мне получить доступ к значениям из каждого элемента XML, чтобы я мог вставлять его по одной строке за раз? как это: INSERT INTO контент (тема, контентдата, контент, автор) VALUES («Предметный текст», 2007-5-21 04:03:00, «текстовое содержание здесь», «JPass78»);

Ответы [ 2 ]

1 голос
/ 17 октября 2011

Вместо использования COLDFUSION для импорта больших файлов XML в базу данных MYSQL используйте команду MYSQL «LOAD XML INFILE».

Вот простой, легкий и быстрый код, который работал для меня:

LOAD XML INFILE 'pathtofile/file.xml' INTO TABLE table_name ROWS IDENTIFIED BY '<item>';

В моем XML-файле используются те же точные имена полей, что и в моей таблице базы данных.ROWS IDENTIFIED BY сообщает команде, что имена полей в моем файле xml будут соответствовать полям базы данных в моей таблице, и они будут находиться между тегами .

К вашему сведению, - это мой собственный формат имен.Ваш файл, вероятно, будет иметь другое имя тега, которое относится к данным, с которыми вы работаете.Например, если ваш xml-файл предназначен для данных о сотрудниках, вы можете вместо этого использовать

Доступно в MYSQL5.5 - Справочник по LOAD XML INFILE можно найти по адресу: http://dev.mysql.com/doc/refman/5.5/en/load-xml.html

1 голос
/ 15 октября 2011

Одна из возможностей - инициализировать данные structure каждый раз, когда вы сталкиваетесь с элементом <item>.Поскольку дочерние элементы проходят (<subject>, <date>, ...), извлеките их текст и добавьте его в свою структуру.Затем, когда вы достигнете элемента </item>, выполните проверку / вставку.Там могут быть лучшие подходы.Но это должно дать вам кое-что для работы ..

Обновление: У меня была догадка, что инструмент массовой загрузки базы данных будет лучшим вариантом.Оказывается, это было;) Подробности смотрите в ответе JPass.

<cfset fis = createObject("java", "java.io.FileInputStream").init(pathToYourFile)>
<cfset bis = createObject("java", "java.io.BufferedInputStream").init(fis)>
<cfset XMLInputFactory = createObject("java", "javax.xml.stream.XMLInputFactory").newInstance()>
<cfset reader = XMLInputFactory.createXMLStreamReader(bis)>

<cfloop condition="#reader.hasNext()#">
    <cfset event = reader.next()>
    <cfif event EQ reader.START_ELEMENT>
        <cfswitch expression="#reader.getLocalName()#">
            <cfcase value="item">
                <!--- start a new data row --->
                <cfset row = {}>
            </cfcase>
            <cfcase value="subject">
                <!--- extract the subject text --->
                <cfset row.subject = reader.getElementText()>
            </cfcase>
            <cfcase value="date">
                <!--- extract the date text --->
                <cfset row.date = reader.getElementText()>
            </cfcase>
            <cfcase value="content">
                <!--- extract the content text --->
                <cfset row.content = reader.getElementText()>
            </cfcase>
            <cfcase value="author">
                <!--- extract the author text --->
                <cfset row.author = reader.getElementText()>
            </cfcase>  
        </cfswitch>
    <cfelseif event EQ reader.END_ELEMENT>
        <!--- we have reached the end of the row. time to insert the data --->
        <cfif reader.getLocalName() eq "item">
            <cfdump var="#row#" label="Debug Row Data">    
            <!--- ... validate / insert "row" data into database --->
        </cfif>
    </cfif>
</cfloop>

<cfset fis.close()>
<cfset reader.close()>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...