C# Extension methods for the XObject class.
using System.Xml.Linq;
using System.Xml;
namespace Hl7.Fhir.Utility
{
public static class XObjectExtensions
{
public static bool TryGetAttribute(this XElement docNode,
XName name, out string value)
{
var attr = docNode.Attribute(name);
if (attr != null)
{
value = attr.Value;
return true;
}
else
{
value = null;
return false;
}
}
/***
* Make sure we handle all possible node types:
* System.Xml.Linq.XObject
* System.Xml.Linq.XAttribute
* System.Xml.Linq.XNode
* System.Xml.Linq.XComment
* System.Xml.Linq.XContainer
* System.Xml.Linq.XDocument
* System.Xml.Linq.XElement
* System.Xml.Linq.XDocumentType
* System.Xml.Linq.XProcessingInstruction
* System.Xml.Linq.XText
*
* Note: XDocumentType, XProcessingInstruction appear only on XDocument
*/
public static XObject FirstChild(this XObject node)
{
var container = node as XContainer;
if (container != null)
{
// Alright, containers may have children, but if this is an
// Element, we need to iterate through the attributes first
var element = container as XElement;
if (element?.FirstAttribute != null)
return element.FirstAttribute;
else
return container.FirstNode;
}
return null;
}
public static XObject NextChild(this XObject node)
{
var n = node as XNode;
if (n != null)
return n.NextNode;
else
{
// If we are not an XNode, we are an attribute (in Linq to Xml hierarchy)
var attr = (XAttribute)node;
if (attr.NextAttribute != null) return attr.NextAttribute;
// out of attributes, continue with our parents first "real" node
return attr.Parent.FirstNode;
}
}
public static string Value(this XObject node)
{
if (node.NodeType == XmlNodeType.Attribute)
{
return ((XAttribute)node).Value;
}
else if (node.NodeType == XmlNodeType.Text)
{
return ((XText)node).Value;
}
else
return null;
}
}
}