F#を使用して特に大きなXML文書を処理しようとしています。ドキュメント全体の読み込みが除外されているので、私は自分の目的に合うようにXmlReaderを使用しようとしています。私の最初のステップは、ノードのシーケンスとしてXML文書を定義することです。F#XML 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
これは、(関数CreateNodeDataによって作成され、単純化のためにここに与えられていない)NODEDATAのシーケンスとしてXML文書を構築します。レイジーリストは、アクティブパターンマッチングを使用するために使用されます。
今、スキーマのパーサは、FParsecのような文法を定義することによって構築されます。例えば、
モナディック構造を追加して、次のコードが与えられた条件に一致する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
代替パーサを表すように付加されます。
私が直面しています問題は、このような
<Node Color="Red" Transparency="90%" Material="Wood"/>
などの要素でXMLを解析しているここで色、透明度、材料が必要な属性である属性は、しかし、彼らの順序は重要ではありません。さらに、他のオプションの属性もあります。私は
これは、次の文字列
xabc,xacb,xbac,xbca,xcab,xcba
方法のいずれかに一致すると等価であるハンドリング
- 配列非依存の属性を表すために、コンビナトリアルパーサを作成するにはどうすればよいです私はそれを簡素化することはできますか?
解析は、XmlReaderをによって解析されたノードデータを使用しています。主な考え方は、XmlReaderの上にXMLスキーマをオーバーレイし、アプリケーションがHasAttributeなどの関数を呼び出さずに直接データを作成するためのフレームワークを提供することです。 –