Unix XML-файл конвертировать в плоский файл - PullRequest
1 голос
/ 17 декабря 2010

У нас есть несколько XML-файлов в Unix.Нам нужно конвертировать их в плоские файлы.И мы выполнили этот анализ для одного уровня XML-файла с использованием C (C использовался, поскольку C может связываться с быстрой загрузкой Teradata, которая является нашей целевой коробкой с использованием inmod, и она будет завершена в течение одного анализа другим способом на других языках, которые нам нужно выполнить два раза для анализаодин для конвертации в плоский файл и один для загрузки ito teradata).то есть приведенный ниже файл

<book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
   </book>

преобразуется в

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~44.95~

. Этого мы достигли, проанализировав файл на языке C. Но увидев исходный формат XML-файла, который представлен ниже.(Пожалуйста, не рассматривайте его как необходимый файл. Я просто даю идею)

<book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
             <modified>2010-01-02</modified>
             <modified>2010-01-03</modified>
      <price>44.95</price>
   </book>

Это должно быть преобразовано в две записи, как кажется.

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02~44.95~
bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-03~44.95~

Но теперь мыощущение, что наш код C будет сложным для этого требования.Поэтому мы рассматриваем другие варианты, которые могут быть легко использованы в Unix.Кто-нибудь может дать нам какие-нибудь рабочие примеры кодов на разных языках / опций для unix?

Ответы [ 4 ]

3 голосов
/ 17 декабря 2010

Вы можете использовать XSLT.Я использую Saxon (Java), который можно запустить в Unix.

Эта таблица стилей обрабатывает оба ваших образца XML:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output  method="text"/>
  <xsl:template match="/book">
    <xsl:choose>
      <xsl:when test="modified">
        <xsl:for-each select="modified">
          <xsl:call-template name="dump-line">
            <xsl:with-param name="pos" select="position()"/>
          </xsl:call-template>          
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="@id"/><xsl:text>~</xsl:text>
        <xsl:value-of select="author"/><xsl:text>~</xsl:text>
        <xsl:value-of select="title"/><xsl:text>~</xsl:text>
        <xsl:value-of select="genre"/><xsl:text>~</xsl:text>
        <xsl:value-of select="price"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="dump-line">
    <xsl:param name="pos"/>
    <xsl:value-of select="/book/@id"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/author"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/title"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/genre"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/modified[$pos]"/><xsl:text>~</xsl:text>
    <xsl:value-of select="/book/price"/>
    <xsl:text>&#x0A;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

Если нет элементов modified, выводится одна запись,Если имеется modified элементов, выводится столько записей, сколько элементов modified.

Пример вывода с измененными элементами:

bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02~44.95
bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-03~44.95
1 голос
/ 17 декабря 2010

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

Однако, если вы загружаете данные в базу данных, почему вы сначала конвертируете их в плоский файл?Вы сказали, что хотите избежать двух проходов один разбор.Похоже, у вас будет один проход для синтаксического анализа XML и вывода в виде плоского файла, а другой - для анализа плоского файла и его ввода в базу данных.Почему бы просто не проанализировать XMl и поместить данные непосредственно в базу данных?

Есть причины, по которым были изобретены форматы, такие как XML, и одна из них заключается в инкапсуляции сложных отношений данных в текстовых документах.Преобразовав в «плоский файл», вы потеряете эту сложность.Если вы собираетесь импортировать данные в среду, которая может справиться с этой сложностью и сохранить эти отношения ... почему бы не сохранить ее?

Есть ли в вашей базе данных API или она может импортировать только плоские файлы?

--- РЕДАКТИРОВАТЬ ---

Проще ответить как часть ответа, чем как серия комментариев.

Во-первых, спасибо за разъяснения.Во-вторых, нет, я не могу предоставить пример кода.В основном, потому что то, что вы хотите, звучит очень специфично.В-третьих, я думаю, у вас есть два варианта:

1) У вас уже загружен код C, уже написанный для анализа XML.Вы должны учитывать стоимость выбрасывания всего этого и повторного написания его на Perl и поддержки этого, в сравнении с затратами на его улучшение для импорта данных непосредственно в вашу базу данных Teradata и затратами на его последующее обслуживание.

2Для Perl существует множество парсеров XML, и, по моему опыту, они значительно упрощают обход XML-дерева / структуры данных, чем в C. Я не фанат Perl, но я написал код для работы с готовыми разобранными XML-деревьями.в Си, и я никогда не мог ненавидеть это.Напротив, делать это в Perl проще и, возможно, даже быстрее.

Существует огромное количество модулей Perl для анализа XML.Я предлагаю вам поискать в Интернете некоторые обзоры, чтобы решить, какой из них проще или лучше всего использовать.

Существует модуль Perl под названием Teradata :: SQL, который должен позволить вам импортировать данные в ваш файл.База данных Teradata.Могут быть и другие модули, которые проще / проще / лучше в использовании.У меня нет опыта ни в одном из них, поэтому я не могу дать рекомендации.Ищите http://www.cpan.org любых модулей, которые могут быть полезны.


И наконец, я НАСТОЯТЕЛЬНО рекомендую убедиться, что вы потратили некоторое время, чтобы убедиться, что структура вашей базы данных Teradata соответствует входящим в нее данным,Как я уже говорил выше, между датами изменения и книгами у вас явно есть взаимосвязь «многие к одному», поэтому вам нужно иметь таблицу дат изменения и таблицу для книг и корректировать отношения «один к одному» в дизайне таблицы.Поместить одну запись в строку, в результате чего для одной книги будет несколько строк с изменением только даты изменения, очень неправильно.Могут быть и другие отношения один к одному, например, автор.Представьте себе книгу Б, написанную авторами А1 и А2 с датами модификации М1 и М2.Если вы используете описанный выше подход, предусматривающий использование одной строки для каждой комбинации, у вас будет 4 записи для одной и той же книги, и похоже, что у вас есть 2 книги с одинаковым названием, но написанные разными авторами.

Потратьте некоторое время, чтобы убедиться, что вы понимаете структуру данных в файлах XML.Это должно быть четко определено DTD.

1 голос
/ 17 декабря 2010

XSLT является опцией;посмотрите инструмент xsltproc .

Или вы также можете гораздо проще XQuery, хотя вам может потребоваться заставить его создавать текст.Следующий скрипт XQuery делает почти то, что вам нужно (только несколько полей в списке):

for $book in doc("book.xml")/book
for $mod in $book/modified
return concat($book/@id, "~", $book/title, "~", $mod, "
")

Вы можете запустить его через Saxon с

java net.sf.saxon.Query '!method=text' script.xq

Еще один популярныйПроцессором XQuery для Unix является XQilla , хотя я не уверен, что он может выводить не в формате XML.

(может быть разумная альтернатива моему неуклюжему способу создания новой строки.)

0 голосов
/ 17 декабря 2010

Как насчет форматирования строки как bk101~Gambardella, Matthew~XML Developer's Guide~Computer~2010-01-02,2010-01-03~44.95~. Конечно, особое внимание следует уделить тому факту, что измененное поле может содержать список значений. Это примерно так же плоско, как вы можете это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...