views:

263

answers:

3

I have a code library that makes heavy use of XPathNavigator to parse some specific xml document. The xml document is cross-referenced, meaning that an element can reference another which has not yet been encountered during parsing:

<ElementA ...>
    <DependentElementX id="1234">
</ElementA>

<ElementX id="1234" .../>

The document doesn't really look like this, but the point is that 1) there is an xml schema that enforces the overall document structure, 2) elements inside the document can reference each other using some IDs, and 3) there is quite a few such cross references between different elements in the document.

The document is parsed in two phases. In the first pass I walk through the document

XPathDocument doc = ...;
XPathNavigator nav = doc.CreateNavigator();
nav.MoveToRoot();
nav.MoveToFirstChild()...

and occasionally 'bookmark' the current position (element) in the document using XPathNavigator.Clone() method. This gives me a lightweight instance of an XPathNavigator which I can store somewhere and use later to jump back to a particular place (element) in my document.

Once I have enough information collected in the first pass (for example, I have made sure there is indeed an ElementX with an id='1234'), I jump back to saved bookmarks (using those saved XPathNavigators) and complete the parsing.

Well, now I'm about to use this library in Silverlight 3.0 and to my horror the XPathNavigator is not in the System.Xml assembly.

Questions:

1) Am I missing something obvious (i.e. XPathNavigator does exist in some shape or form, for example in a toolkit or a freeware library)?

2) If I do have to make modifications in the code, what would be the best way to go? Ideally, I would like to make minimal changes, not to rewrite 80% of the code just to be able to use something like XLinq.

To resume, in case I have to give up XPathNavigator, all I need is a way to bookmark places in my document and to get back to them so that I can continue to iterate from where I left off.

Thanks in advance for any help/ideas.

A: 

There are tons of ways: http://stackoverflow.com/questions/220867/how-to-deal-with-xml-in-c/220981#220981

You can still use Linq to XML just minus the linq syntax and use the Linq Extension methods.

nyxtom
@nyxtom: There aren't "tons of ways" to handle XML in __Silverlight__. There are in fact only 2 `XmlReader` or `XDocument`.
AnthonyWJones
The twist here is the availability in Silverlight, which reduces the number of choices dramatically. XLinq definitely remains one of them though.
vladimir
+1  A: 

You are not missing something obvious, there is no implementation of XPathNavigator or XPathDocument in the Silverlight versions of the libraries.

The "best way to go" is highly subjective and would really depend on how many lines of code are really depending on XPathNavigator. However I see a couple of choices.

  • Go ahead and re-write the code using XDocument, XElement etc from the System.Xml.Linq namepsace. This may not be as bad a choice as you might think.
  • Wrap Xml-to-Linq objects in your own implementation of those properties and methods of the XPathNavigator that you are actually using. It shouldn't be too hard re-create most the features of the XPathNavigator against the Xml-to-Linq objects. You can then run your existing code against your own XPathNavigator.
AnthonyWJones
Thanks Anthony, both proposals are sound. I'm currently inclined towards the usage of XDocument/XElement, but that's mostly because I'm unfamiliar with XLinq. In any case it seems I will have to give up document validation using my XSD schema, unless I manage to convert it (correctly!) into a dtd.
vladimir
@Vladimir: I personally find it difficult separating XDocument/XElement from "XLinq" since the extension methods which describe this feature are in the same namespace as `XDocument`.
AnthonyWJones
@Anthony: true, the separation that I was using is non-existent.
vladimir
A: 

XPath (xdoc.XPathSelectElements) is available in Silverlight 4: here's an online test tool.

Chris S