Я пытаюсь обработать особенно большой XML-документ, используя F #.Поскольку загрузка всего документа исключена, я пытаюсь использовать XmlReader для своих целей.Мой первый шаг - определить XML-документ как последовательность узлов.
// Read XML as a lazy sequence
let Read (s:string) =
let r = XmlReader.Create s
let src = seq {
while r.Read()
do
if XmlNodeType.Element = r.NodeType then
yield CreateNodeData r
while r.MoveToNextAttribute()
do
yield CreateNodeData r
done
else
yield CreateNodeData r
done
}
LazyList.ofSeq src
Это создает XML-документ как последовательность NodeData (которая создается функцией CreateNodeData и не приводится здесь для простоты).Ленивый список используется для использования активного сопоставления с образцом.
Теперь синтаксический анализатор для схемы создается путем определения грамматики, такой как FParsec.Например,
type NodeSeq = NS of LazyList<NodeData>
(*
Define a generic parser that takes an XML Reader and returns a singleton
list containing parsed element and unparsed parser. Failure is denoted by
an empty list
*)
type 'a Parser = P of ( NodeSeq -> list<'a * NodeSeq > )
И добавление монадических конструкций для создания монадического синтаксического анализатора таким образом, чтобы следующий код анализировал NodeData, который соответствует заданным критериям.
let item = P ( fun inp ->
match inp with
| NS(LazyList.Nil) -> []
| NS(LazyList.Cons(a,b)) -> [(a,NS(b))]
)
let nodeFilter (f: NodeData -> bool) =
parser {
let! c = item
if (f c) then
return c
}
Также добавлен оператор выбора (+++)
такой, что p +++ q
представляет альтернативные парсеры.
Проблема, с которой я сталкиваюсь, заключается в анализе XML с таким элементом, как
<Node Color="Red" Transparency="90%" Material="Wood"/>
Здесь атрибуты Color, Transparency и Material являются обязательными атрибутами, однакоИх последовательность не имеет значения.Кроме того, могут быть другие необязательные атрибуты.Как создать комбинаторный анализатор для представления
- независимой от последовательности обработки атрибутов
- необязательных атрибутов
Это эквивалентно сопоставлению с любой из следующих строк
xabc,xacb,xbac,xbca,xcab,xcba
Как мне это упростить?