Get InnerXML from XPathNavigator

First thanks a lot to my colleague, Eunge. He helped me to solve this problem. And it’s really a long time I haven’t written .Net codes.

Sometimes we need to get InnerXML from the XPathNodeIterator, especially when you are writing codes in XSLT.

If you are using .Net Framework 2.0, it’s very easy. There is a property, InnerXML, in XPathNavigator, and from disassembled code we could find new functionalities of XMLWriter. But if you are using .Net 1.1, it’s really not quite convenient to do it. And there are two concrete classes which inherit abstract class XPathNavigator. One is XPathDocumentNavigator, the other is DocumentXPathNavigator. There is an important difference between two classes. DocumentXPathNavigator implements the interface IHasXmlNode, but XPathDocumentNavigator not. That means if your XPathNavigator is DocumentXPathNavigator, it’s easy to get InnerXML.

[code=csharp]
XPathNavigator nav = dom.CreateNavigator();
// do some select
String innerXml = ((IHasXmlNode)nav).GetNode().InnerXML;
[/code]

Unfortunately, if your XPathNavigator is XPathDocumentNavigator, you have to write many codes. Codes below are sample.

[code=csharp]
public string GetInnerXML(System.Xml.XPath.XPathNodeIterator nodeIterator)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
System.Xml.XPath.XPathNavigator navigator = nodeIterator.Current;
System.Xml.XmlNode rootNode =doc.CreateNode(this.ConvertXmlNodeType(navigator.NodeType), nodeIterator.Current.Name, nodeIterator.Current.NamespaceURI);
doc.AppendChild(rootNode);
this.SetChildNode(rootNode, nodeIterator);
return doc.InnerXml;
}
private void SetChildNode(System.Xml.XmlNode parentNode, System.Xml.XPath.XPathNodeIterator parentIterator)
{
System.Xml.XPath.XPathNodeIterator childIterator = parentIterator.Current.SelectChildren(System.Xml.XPath.XPathNodeType.All);
while(childIterator.MoveNext())
{
System.Xml.XPath.XPathNavigator navigator = childIterator.Current;
System.Xml.XmlNode childNode = parentNode.OwnerDocument.CreateNode(this.ConvertXmlNodeType(navigator.NodeType), navigator.Name, navigator.NamespaceURI);
parentNode.AppendChild(childNode);
if(childNode.NodeType == System.Xml.XmlNodeType.Element)
{
this.SetChildNode(childNode, childIterator);
System.Xml.XPath.XPathNodeIterator attrIterator = navigator.Select(”@*”);
while(attrIterator.MoveNext())
{
System.Xml.XPath.XPathNavigator attrNavigator = attrIterator.Current;
System.Xml.XmlAttribute attribute = childNode.OwnerDocument.CreateAttribute(attrNavigator.Prefix, attrNavigator.LocalName, attrNavigator.NamespaceURI);
attribute.Value = attrNavigator.Value;
childNode.Attributes.Append(attribute);
}
}
else if(childNode.NodeType == System.Xml.XmlNodeType.Text)
{
childNode.Value = navigator.Value;
}
else if (childNode.NodeType == System.Xml.XmlNodeType.Attribute)
{
childNode.Value = navigator.Value;
} }
}
private System.Xml.XmlNodeType ConvertXmlNodeType(System.Xml.XPath.XPathNodeType nodeType)
{
switch(nodeType)
{
case System.Xml.XPath.XPathNodeType.Element:
return System.Xml.XmlNodeType.Element;
case System.Xml.XPath.XPathNodeType.Root:
return System.Xml.XmlNodeType.Element;
case System.Xml.XPath.XPathNodeType.Attribute:
return System.Xml.XmlNodeType.Attribute;
case System.Xml.XPath.XPathNodeType.Text:
return System.Xml.XmlNodeType.Text;
default:
return System.Xml.XmlNodeType.Element;
}
}
[/code]

Hope it is useful.

Related Posts

Leave a Reply