title: F# XML Parsing using XMLReader
body: <p>I am trying to process a particularly large XML document using F#. Since loading whole document is ruled out, I am trying to use XmlReader to serve my purpose. My first step is to define XML document as sequence of nodes.</p>
  
  
  
  <pre class="lang-ml prettyprint-override"><code>// 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
  </code></pre>
  
  <p>This builds XML document as a sequence of NodeData (which is created by function CreateNodeData, and not given here for simplicity). The lazy list is used for using active pattern matching.</p>
  
  <p>Now the parser for the schema is constructed by defining grammar like FParsec. For example</p>
  
  <pre class="lang-ml prettyprint-override"><code>type NodeSeq = NS of LazyList&lt;NodeData&gt;
  
  (* 
  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 -&gt; list&lt;'a * NodeSeq &gt; )
  </code></pre>
  
  <p>And adding monadic constructs to create a monadic parser such that following code parses NodeData that matches given criteria.</p>
  
  <pre class="lang-ml prettyprint-override"><code>let item = P ( fun inp -&gt;
      match inp with
      | NS(LazyList.Nil)          -&gt; [] 
      | NS(LazyList.Cons(a,b))    -&gt; [(a,NS(b))]
      )
  
  let nodeFilter (f: NodeData -&gt; bool) = 
      parser {
          let! c = item
          if (f c) then
              return c
          }
  </code></pre>
  
  <p>Also, the choice operator <code>(+++)</code> is added such that <code>p +++ q</code> represents alternative parsers.</p>
  
  <p>The problem that I am facing is parsing XML with element such as</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;Node Color="Red" Transparency="90%" Material="Wood"/&gt;
  </code></pre>
  
  <p>Here the attributes Color, Transparency and Material are required attributes, however, their sequence is immaterial. In addition, there can be other optional attributes. How can I create a combinatorial parser to represent</p>
  
  <ul>
  <li>sequence independent attribute handling</li>
  <li>optional attributes</li>
  </ul>
  
  <p>This is equivalent to matching any one of following strings</p>
  
  <p><code>xabc,xacb,xbac,xbca,xcab,xcba</code></p>
  
  <p>How can I simplify it?</p>