Java: учитывая список имен файлов, убедитесь, что соответствующий XML содержит только информацию об этих файлах - PullRequest
0 голосов
/ 19 июля 2011

У меня есть список файлов (от 20000 до 50000 файлов) и большой XML-файл.Я хочу, чтобы файл XML содержал только информацию о файле в List.

Например, допустим, в нашем списке только файл XYZ, а файлы XML выглядят так, как показано ниже.

<?xml version="1.0" encoding="ISO-8859-1"?>
<index>
<document>
    <entry number="1">
        <commentfield>
            <name>FileName</name>
            <value>XYZ</value>
        </commentfield>
    </entry>
    <entry number="2">
        <commentfield>
            <name>Note</name>
            <value>03-000</value>
        </commentfield>
    </entry>
</document>
<document>
    <entry number="1">
        <commentfield>
            <name>FileName</name>
            <value>ABC</value>
        </commentfield>
    </entry>
</document>
...
</index>

XML содержит информацию о двух файлах XYZ и ABC.Поэтому я не хочу, чтобы окончательный XML содержал last <document> ... ABC ... </document>, поскольку этого document ABC нет в нашем Списке.У меня есть требования, успешно работающие в KSH скрипте, но он работает слишком медленно (более 4 часов для 22000 файлов. Ну, он также делает что-то еще).Но я решил перейти на Java для повышения производительности.Что я сделал, так это прочитал строку за строкой в ​​строку, и когда я нажал </document>, я проанализировал имя файла, проверил, существуют ли эти файлы в нашем списке, и если это так, запишите все это <document> ... </document>другой файл xml, затем прочитайте снова следующий <document>.Есть ли лучший способ?

Уже в состоянии написать код для достижения этой цели с помощью анализатора DOM.Код длинный, поэтому, если вам это нужно, пожалуйста, пишите мне в личку.за помощь тывм

Ответы [ 4 ]

2 голосов
/ 19 июля 2011

«Разбор» ввода XML самостоятельно с использованием регулярных выражений или любого другого хрупкого решения, которое наложит ненужные ограничения на формат текста ввода (вокруг пробела и тому подобное).В этом нет необходимости, когда библиотека Java поставляется с несколькими синтаксическими анализаторами XML.

Использование DOM может быть самым простым способом, если вы можете гарантировать, что ваш входной XML не станет слишком большим для того, чтобы выпадать в память приодин раз.Вы можете:

  1. Считать XML в структуру DOM
  2. Обойти DOM и изменить его, удалив ненужные узлы
  3. Записать измененный DOM в новый файлиспользуя Transformer.Пример здесь .

Более эффективным вариантом может быть StAX, который не требует считывания всего ввода сразу.Я не использовал его, но у него есть возможность читать, а также писать документы.Вы можете прочитать элемент <document> одновременно и записать его обратно в выходной файл, если он есть в списке.Немного учебник здесь .

1 голос
/ 19 июля 2011

Игнорирование на данный момент подробностей о лучшем способе синтаксического анализа и перезаписи XML, базовой стратегии однократного чтения файла XML и поиска каждого имени файла в списке, кажется разумным.

Тем не менее, вы можете улучшить их способ проверки на наличие в списке имен файлов (вы не указываете, как вы это делаете). Пара возможностей:

  1. Поместите имена файлов в Set и проверьте наличие в наборе, что будет O (1) или O (log N) операция
  2. Сортировка списка имен файлов и выполнение двоичного поиска, который будет операцией O (log N).

В любом случае было бы лучше, чем простой линейный поиск по несортированному списку.

1 голос
/ 19 июля 2011

Есть несколько способов приблизиться к этому:

XSL T сделает это очень просто, если у вас есть фиксированный список ввода, вы можете написать преобразование, которое выбирает только допустимые элементы и выводит их,Таким образом, вам не нужно писать какой-либо код, и вы можете использовать что-то вроде xsltproc , что очень быстро!

Это то, что я бы попробовал сначала, потому что он специально создан для преобразования XML в другой XML, он меньше кода и меньше кода, меньше обслуживания.

Вотпредставление о том, как начать, выводит все элементы <document/>, где элементы <value/> не равны ABC.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml"/>

    <!-- this matches ALL nodes and ALL attributes -->
    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <!-- this matches the entire document element where value = 'ABC' -->
    <xsl:template match="document[entry[commentfield[value[(text()='ABC')]]]]"/>

</xsl:stylesheet>

На XSLT имеется множество ресурсов и хороших книг.все, что вам нужно сделать, это предоставить белый список поддерживаемых <value/> элементов и изменить логику в моем примере.

Если у вас есть .xsd или , вы можете создать один , ваш вводФайл не выглядит очень сложным, вы можете использовать JAXB для автоматической генерации иерархии объектов, чтобы проанализировать входной файл, а затем вы можете просмотреть получившийся граф объектов и удалить все, что не соответствует вашим критериям, и перенести его обратно в файл.

JAXB не очень жизнеспособен, если размер файла больше, чем умещается в памяти.

0 голосов
/ 19 июля 2011

Вы можете использовать Xpath для получения элементов, если вы знаете структуру xml, вы можете удалить эти элементы. В зависимости от того, как вы обрабатываете ваш XML, вы можете использовать DOM (вероятно, не очень хорошая идея для больших XML)

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