Потоковая оценка XPath
Есть ли готовые к выпуску библиотеки для потоковой обработки оценок XPath с предоставленным xml-документом? Мои исследования показывают, что большинство существующих решений загружают весь DOM-дерево в память, прежде чем оценивать выражение xpath.
Ответы
Ответ 1
Будет ли это практичным для полной реализации XPath, учитывая, что синтаксис XPath позволяет:
/AAA/XXX/following::*
и
/AAA/BBB/following-sibling::*
что подразумевает требования внешнего вида? то есть от конкретного node вам все равно придется загружать остальную часть документа.
Документ для библиотеки Nux (в частности StreamingPathFilter) делает эту точку и ссылается на некоторые реализации, которые полагаются на подмножество XPath. Nux утверждает, что выполняет некоторые возможности потокового запроса, но с учетом вышесказанного будут некоторые ограничения в отношении реализации XPath.
Ответ 2
XSLT 3.0 обеспечивает потоковый режим обработки, и это станет стандартом, когда спецификация XSLT 3.0 W3C станет Рекомендация W3C.
На момент написания этого ответа (май 2011 г.) Saxon предоставляет поддержку для потоковой передачи XSLT 3.0.
Ответ 3
Существует несколько вариантов:
-
DataDirect Technologies продает реализацию XQuery, где, где это возможно, используются проекции и потоки. Он может обрабатывать файлы в диапазоне с несколькими гигабайтами - например, больше доступной памяти. Это потокобезопасная библиотека, поэтому ее легко интегрировать. Java-только.
-
Saxon - это версия с открытым исходным кодом, с более дорогим двоюродным братом по умеренной цене, которая будет транслировать некоторые контексты. Java, но также с портом .net.
-
MarkLogic и eXist - это базы данных XML, которые, если ваш XML загружается в них, будут обрабатывать XPaths довольно интеллектуально.
Ответ 4
Попробуйте Joost.
Ответ 5
Хотя у меня нет практического опыта, я подумал, что стоит упомянуть QuiXProc (http://code.google.com/p/quixproc/). Это потоковый подход к XProc и использует библиотеки, которые обеспечивают поддержку потоковой передачи XPath среди других.
Ответ 6
FWIW, я использовал Nux потоковый фильтр xpath запросов с очень большими ( > 3 ГБ) файлами, и он работал безупречно и использовал очень мало памяти. Мой вариант использования несколько отличается (не валидация), но я настоятельно рекомендую вам сделать снимок с помощью Nux.
Ответ 7
Думаю, я поеду на специальный код. Библиотека .NET приближает нас к цели, если вы просто хотите прочитать некоторые пути XML-документа.
Так как все решения, которые я вижу до сих пор, относятся только к подмножеству XPath, это тоже такое решение. Подмножество действительно мало.:)
Этот код С# считывает 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();