Потоковая оценка XPath
-
13-09-2019 - |
Вопрос
Существуют ли какие-либо готовые библиотеки для потоковой оценки выражений XPath на основе предоставленного XML-документа?Мои исследования показывают, что большинство существующих решений загружают в память все DOM-дерево перед оценкой выражения xpath.
Решение
Будет ли это практично для полной реализации XPath, учитывая, что синтаксис XPath позволяет:
/AAA/XXX/following::*
и
/AAA/BBB/following-sibling::*
что подразумевает требования прогнозирования?то естьиз определенного узла вам все равно придется загружать остальную часть документа.
Документ для Нукс библиотека (в частности StreamingPathFilter) подчеркивает это и ссылается на некоторые реализации, основанные на подмножество из XPath.Nux утверждает, что выполняет некоторые возможности потоковой передачи запросов, но, учитывая вышеизложенное, будут некоторые ограничения с точки зрения реализации XPath.
Другие советы
XSLT 3.0 обеспечивает потоковый режим обработки и это станет стандартом, а спецификация XSLT 3.0 W3C станет Рекомендацией W3C.
На момент написания этого ответа (май 2011 г.) Saxon предоставил некоторые поддержка потоковой передачи XSLT 3.0 .
Есть несколько вариантов:
DataDirect Technologies продает реализацию XQuery где это возможно, используется проекция и потоковая передача.Он может обрабатывать файлы размером в несколько гигабайт - например.больше доступной памяти.Это потокобезопасная библиотека, поэтому ее легко интегрировать.Только Java.
саксонский это версия с открытым исходным кодом, имеющая более дорогую версию по умеренной цене, которая в некоторых контекстах поддерживает потоковую передачу.Java, но также с портом .net.
МаркЛогик и существовать представляют собой базы данных XML, которые, если в них загружен ваш XML, будут довольно интеллектуально обрабатывать XPath.
Пытаться Йост.
Хотя у меня нет практического опыта работы с ним, я подумал, что стоит упомянуть QuiXProc ( http://code.google.com/p/quixproc/ ).Это потоковый подход к XProc, в котором используются библиотеки, которые, среди прочего, обеспечивают потоковую поддержку XPath.
Кстати, я использовал запросы xpath потокового фильтра Nux к очень большим (> 3 ГБ) файлам, и оба они работали безупречно и использовали очень мало памяти.Мой вариант использования немного отличается (не ориентирован на проверку), но я настоятельно рекомендую вам попробовать его с Nux.
Я думаю, что я выберу собственный код.Библиотека .NET подводит нас довольно близко к цели, если кто-то просто хочет прочитать некоторые пути XML-документа.
Поскольку все решения, которые я вижу до сих пор, учитывают только подмножество XPath, это тоже решение такого рода.Хотя подмножество действительно маленькое.:)
Этот код C# читает XML-файл и подсчитывает узлы по явному пути.Вы также можете легко работать с атрибутами, используя xr["attrName"]
синтаксис.
int c = 0;
var r = new System.IO.StreamReader(asArgs[1]);
var se = new System.Xml.XmlReaderSettings();
var xr = System.Xml.XmlReader.Create(r, se);
var lstPath = new System.Collections.Generic.List<String>();
var sbPath = new System.Text.StringBuilder();
while (xr.Read()) {
//Console.WriteLine("type " + xr.NodeType);
if (xr.NodeType == System.Xml.XmlNodeType.Element) {
lstPath.Add(xr.Name);
}
// It takes some time. If 1 unit is time needed for parsing the file,
// then this takes about 1.0.
sbPath.Clear();
foreach(object n in lstPath) {
sbPath.Append('/');
sbPath.Append(n);
}
// This takes about 0.6 time units.
string sPath = sbPath.ToString();
if (xr.NodeType == System.Xml.XmlNodeType.EndElement
|| xr.IsEmptyElement) {
if (xr.Name == "someElement" && lstPath[0] == "main")
c++;
// And test simple XPath explicitly:
// if (sPath == "/main/someElement")
}
if (xr.NodeType == System.Xml.XmlNodeType.EndElement
|| xr.IsEmptyElement) {
lstPath.RemoveAt(lstPath.Count - 1);
}
}
xr.Close();