Daniel writes about transforming a portion of XML document using XPathNavigatorReader. That's a common bad surprise for MSXML-experienced people, who used to fooNode.transformNode() method, where only fooNode and its descendants are visible in XSLT. In .NET that's different - no matter which DOM node you pass to XslTransform.Transform() method, the whole XmlDocument tree is visisble in XSLT. MSDN suggests to load the portion of XML you want to transform into a temporary XmlDocument and pass it to the transformation. Too bad.
What Daniel proposes instead is to load the portion of XML to be transformed into a temporary XPathDocument instead of XmlDocument. Well, that's better, but what I'd like to ask is why do one need any temporary tree at all? It's a piece of cake to write custom XPathNavigator that would limit navigation only to a specified subtree. I did that once with XmlNodeNavigator, which represents XPathNavigator over XmlNode. Less than 10Kb of code. It's ideal solution to transform only a subtree of an XmlDocument. No temporary objects, just lightweight code between XmlDocument and XSLT that limits navigation not higher that specified node.
That's perfect for XmlDocument. For XPathDocument we need another one. Or better we need generic XPathNavigatorNavigator (did we really go nuts with these XML beasts?). XPathNavigatorNavigator should allow to navigate over given XPathNavigator, but should not allow to move it outside the subtree. Comments?
XPathNavigatorReader and XmlNodeNavigator are both parts of Mvp.Xml project.
Joe, the answer depends on API you are using. If it's XmlDocument, you can create new element and assign comment value to its InnerXml property. Alternatively instead of commenting you can move element to another branch of the tree (e.g. deleted contacts).
I need a help!
Maybe one of you guys culd turn on the light for me.
I have a xml file with data like name, phone and birthday date from my friends.
I am building an application to manage this "database".
When I lost contact with a friend, I comment it´s node in the xml file (running very well).
But ...
Is there a way to reenable (make this comment node became an element node again) using something else then a text editor?
Thanks for any help
Joe
Good name I think. Self-explaining and follows naming conventions. I wish I was such good at naming :)
I say your updates to your classes. Cool :)
And now, users of the Mvp.Xml project (http://sf.net/projects/mvp-xml) also have the same functionality for arbitrary XPathNavigator implementations: http://weblogs.asp.net/cazzu/posts/164243.aspx. I called it the SubtreeXPathNavigator... how does it sound?
It is an elegant solution, much better than loading a new XMLDocument with the outerXML of the node you want to transform.
Eventhough, if you modify the stylesheet, you may also transform only a part of XML document while keeping the context, i.e. the ancestors, sibblings, ...
You may want to take a look at http://www.flowgroup.fr/tech_transformNodeWithStartingMode_us.htm.
You're definitely right Oleg. Your XmlNodeNavigator is the appropriate one to replace the sub-XmlDocument loading problem. However, I also wanted to stress (and move users to) the more performant XPathDocument for transformations.
I'll investigate a XPathSubNavigator (?!) to limit navigation scope. Looks like an interesting thing to do, and will completely avoid generating a new XPathDocument....
So, the user now has XmlNodeNavigator if they already have an XmlDocument, and XPathNavigatorReader if they have an XPathDocument instead.
BTW, you really need to document and create a buch of tests for your classes ;) If I've some spare time I will try to do if for you.
Done with documentation and almost done with tests, Daniel!
Well, if I understand correctly, namespace navigation is simple: on each elenent node (it's only elements who can bear namespace nodes), there is a list of namespace nodes to expose - one implicit (xml namespace) and one for each namespace in effect on the element.
WRT XmlNodeNavigator and hypothethical XPathNavigatorNavigator they can rely on underlying XPathNavigators when exposing namespace nodes.
I was refering to the namespaces mostly because of the lack of correct namspace handling examples.
Because of that lack, and the underdocumentation of what the namespace-related methods (MoveToFirstNamespace/ MoveToNextNamespace/ MoveToNamespace/ GetNamespace) should expose exactly (the framework docs basically just refer to the XML specs), I am still confused what those methods should expose.
And therefore I don't know for sure, but can imagine, that there might be problems with namespaces being declared outside the exposed part of the document, which should be 'transferred' to the document element of the exposed branch.
But then again, it might just be my lack of understanding of how Namespaces should be handled in XPathNavigator that causes me to see problems where there are none...
You are right about MoveToId() (the same problem exists with MoveTo())
Well, I believe inefficiency in couple of rarely used methods is quite reasonable price.
And which namespace effects do you mean?
I have been thinking a bit about something like your XPathNavigatorNavigator a few weeks ago (but didn't implement it yet). The only problematic function is MoveToId(). To handle it correctly, you need to check if the parent implementation moves to a node that is in the exposed tree at all. That is not too hard to get working, but will probably not be very efficient.
Also, there may be some effects on the Namespace navigation methods. But then, I have yet to see a public source XPathNavigator subclass that handles namespaces correctly at all. All implementations I have seen always return String.Empty, which is not a valid implementation, even for navigators that don't handle namespaces, because the default xml: namespace is always there...