Большой однострочный анализ XML-файла: самый эффективный подход? - PullRequest
2 голосов
/ 15 марта 2012

Я пытаюсь определить, каков наиболее эффективный способ анализа файлов .svclog.Чтобы дать вам больше контекста, файлы .svclog, с которыми я имею дело, выглядят так, как в http://msdn.microsoft.com/en-us/library/aa751795.aspx. Логика трассировки создает <E2ETraceEvent/> элементов, а помещает их все в одну строку в a.файл svclog, так что в итоге вы получите однострочный XML-файл стоимостью 10 с, например:

<E2ETraceEvent [...]</E2ETraceEvent><E2ETraceEvent [...] </E2ETraceEvent>...

Какой мой самый эффективный способ чтения по одному элементу <E2ETraceEvent/> за раз из этой гигантской строки?Я знаю, что существуют инструменты, которые могут в основном сделать отступ для XML и сохранить изменения либо в том же файле, либо в отдельном файле.Это дополнительный шаг, который я бы предпочел пропустить, поскольку производительность будет очень важна, учитывая количество этих файлов, которые мне, возможно, придется обработать.Я не хочу делать отступ для сотен толстых файлов, прежде чем я смогу даже начать их обработку.

Я мог бы загрузить весь файл в память и обработать его как строку (они ограничены 30 мегабайтами вв моем случае), но я предполагаю реализовать какую-то логику «объединения журналов» в будущем, где мне может понадобиться сшить сотни этих файлов, и поэтому загрузка их всех в память за раз просто не произойдет.

Я мог бы использовать регулярное выражение с "<E2ETraceEvent.*?</E2ETraceEvent>" и продвигать по одному элементу за раз (это вообще эффективно?).Я мог бы на самом деле вручную реализовать конечный автомат, который будет читать по одному символу за раз.Это уже звучит плохо:)

Тонны вариантов, но я ищу что-то действительно чистое и элегантное.

PS.Действительно ли при синтаксическом анализе принято иметь дело с однострочными файлами?Раньше я не делал слишком много работы по анализу, но почти все инструменты, с которыми я работал, полагаются на чтение x строк одновременно.Все это становится совершенно бесполезным, как только у вас нет ни одной новой строки во всем файле.

Ответы [ 2 ]

2 голосов
/ 18 апреля 2012

Если у кого-то возникли проблемы с испорченными следами, я сделал этот скрипт powershell.

function process-event
{
    $dest = $args[1]
    Get-ChildItem $args[0] | 
        Select-String "([<]E2ETraceEvent.*?(?=[<]E2ETraceEvent))" -AllMatches |
            ForEach-Object { $matches = $_.Matches; 
                foreach ($m in $matches) {  
                    Add-Content -Path $dest -Value $m.Value } };
}

function process-log
{
    '<?xml version="1.0" encoding="utf-8"?><Tracing>' | Out-File $args[1]
    process-event $args[0] $args[1]
    '</Tracing>' | Out-File $args[1] -append
}

process-log .\the_log.svclog .\the_log_fix.svclog

Обновлено! Это не очень быстро, мне нужно только для 300 МБ файлов, но это исправит их и не сожжет всю оперативную память.

2 голосов
/ 15 марта 2012

Поскольку у вас есть фрагменты документа, а не обычные документы, вы можете использовать базовые классы XmlReader для его обработки :

// just a test string... XmlTextReader can take a Stream as first argument instead
var elements = @"<E2ETraceEvent/><E2ETraceEvent/>";

using (var reader = new XmlTextReader(elements, XmlNodeType.Element, null))
{
    while (reader.Read())
    {
        Console.WriteLine(reader.Name);
    }
}

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

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