using System.Collections;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
XAttribute attr_first, attr_last;
bool explicit_is_empty = true;
- public XElement (XName name, object value)
+ public XElement (XName name, object content)
{
+ if (name == null)
+ throw new ArgumentNullException ("name");
this.name = name;
- Add (value);
+ Add (content);
}
- public XElement (XElement source)
+ public XElement (XElement other)
{
- name = source.name;
- Add (source.Attributes ());
- Add (source.Nodes ());
+ if (other == null)
+ throw new ArgumentNullException ("other");
+ name = other.name;
+ Add (other.Attributes ());
+ Add (other.Nodes ());
}
public XElement (XName name)
{
+ if (name == null)
+ throw new ArgumentNullException ("name");
this.name = name;
}
- public XElement (XName name, params object [] contents)
+ public XElement (XName name, params object [] content)
{
+ if (name == null)
+ throw new ArgumentNullException ("name");
this.name = name;
- Add (contents);
+ Add (content);
}
- public XElement (XStreamingElement source)
+ public XElement (XStreamingElement other)
{
- this.name = source.Name;
- Add (source.Contents);
+ if (other == null)
+ throw new ArgumentNullException ("other");
+ this.name = other.Name;
+ Add (other.Contents);
}
+ [CLSCompliant (false)]
public static explicit operator bool (XElement element)
{
if (element == null)
throw new ArgumentNullException ("element");
- return XmlConvert.ToBoolean (element.Value);
+ return XUtil.ConvertToBoolean (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator bool? (XElement element)
{
if (element == null)
return null;
- return element.Value == null ? (bool?) null : XmlConvert.ToBoolean (element.Value);
+ return element.Value == null ? (bool?) null : XUtil.ConvertToBoolean (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator DateTime (XElement element)
{
if (element == null)
throw new ArgumentNullException ("element");
- return XmlConvert.ToDateTime (element.Value, XmlDateTimeSerializationMode.RoundtripKind);
+ return XUtil.ToDateTime (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator DateTime? (XElement element)
{
if (element == null)
return null;
- return element.Value == null ? (DateTime?) null : XmlConvert.ToDateTime (element.Value, XmlDateTimeSerializationMode.RoundtripKind);
+ return element.Value == null ? (DateTime?) null : XUtil.ToDateTime (element.Value);
+ }
+
+#if !TARGET_JVM // Same as for System.Xml.XmlConvert.ToDateTimeOffset
+
+ [CLSCompliant (false)]
+ public static explicit operator DateTimeOffset (XElement element)
+ {
+ if (element == null)
+ throw new ArgumentNullException ("element");
+ return XmlConvert.ToDateTimeOffset (element.Value);
+ }
+
+ [CLSCompliant (false)]
+ public static explicit operator DateTimeOffset? (XElement element)
+ {
+ if (element == null)
+ return null;
+
+ return element.Value == null ? (DateTimeOffset?) null : XmlConvert.ToDateTimeOffset (element.Value);
}
+#endif
+
+ [CLSCompliant (false)]
public static explicit operator decimal (XElement element)
{
if (element == null)
return XmlConvert.ToDecimal (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator decimal? (XElement element)
{
if (element == null)
return element.Value == null ? (decimal?) null : XmlConvert.ToDecimal (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator double (XElement element)
{
if (element == null)
return XmlConvert.ToDouble (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator double? (XElement element)
{
if (element == null)
return element.Value == null ? (double?) null : XmlConvert.ToDouble (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator float (XElement element)
{
if (element == null)
return XmlConvert.ToSingle (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator float? (XElement element)
{
if (element == null)
return element.Value == null ? (float?) null : XmlConvert.ToSingle (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator Guid (XElement element)
{
if (element == null)
return XmlConvert.ToGuid (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator Guid? (XElement element)
{
if (element == null)
return element.Value == null ? (Guid?) null : XmlConvert.ToGuid (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator int (XElement element)
{
if (element == null)
return XmlConvert.ToInt32 (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator int? (XElement element)
{
if (element == null)
return element.Value == null ? (int?) null : XmlConvert.ToInt32 (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator long (XElement element)
{
if (element == null)
return XmlConvert.ToInt64 (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator long? (XElement element)
{
if (element == null)
return element.Value == null ? (ulong?) null : XmlConvert.ToUInt64 (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator TimeSpan (XElement element)
{
if (element == null)
return XmlConvert.ToTimeSpan (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator TimeSpan? (XElement element)
{
if (element == null)
return element.Value == null ? (TimeSpan?) null : XmlConvert.ToTimeSpan (element.Value);
}
+ [CLSCompliant (false)]
public static explicit operator string (XElement element)
{
if (element == null)
public XName Name {
get { return name; }
set {
- if (name == null)
- throw new ArgumentNullException ("value");
+ if (value == null)
+ throw new ArgumentNullException ("Name");
+ OnNameChanging (this);
name = value;
+ OnNameChanged (this);
}
}
static void DefineDefaultSettings (XmlReaderSettings settings, LoadOptions options)
{
-#if NET_2_1
+#if MOONLIGHT
// 2.1 has a DtdProcessing property which defaults to DtdProcessing.Prohibit
settings.DtdProcessing = DtdProcessing.Parse;
#else
}
}
- public static XElement Load (TextReader tr)
+ public static XElement Load (TextReader textReader)
{
- return Load (tr, LoadOptions.None);
+ return Load (textReader, LoadOptions.None);
}
- public static XElement Load (TextReader tr, LoadOptions options)
+ public static XElement Load (TextReader textReader, LoadOptions options)
{
XmlReaderSettings s = CreateDefaultSettings (options);
- using (XmlReader r = XmlReader.Create (tr, s)) {
+ using (XmlReader r = XmlReader.Create (textReader, s)) {
return LoadCore (r, options);
}
}
}
}
+#if MOONLIGHT || MOBILE || NET_4_0
+ public static XElement Load (Stream stream)
+ {
+ return Load (stream, LoadOptions.None);
+ }
+
+ public static XElement Load (Stream stream, LoadOptions options)
+ {
+ XmlReaderSettings s = new XmlReaderSettings ();
+ DefineDefaultSettings (s, options);
+
+ using (XmlReader r = XmlReader.Create (stream, s)) {
+ return LoadCore (r, options);
+ }
+ }
+#endif
+
internal static XElement LoadCore (XmlReader r, LoadOptions options)
{
r.MoveToContent ();
return e;
}
- public static XElement Parse (string s)
+ public static XElement Parse (string text)
{
- return Parse (s, LoadOptions.None);
+ return Parse (text, LoadOptions.None);
}
- public static XElement Parse (string s, LoadOptions options)
+ public static XElement Parse (string text, LoadOptions options)
{
- return Load (new StringReader (s), options);
+ return Load (new StringReader (text), options);
}
public void RemoveAll ()
attr_last.Remove ();
}
- public void Save (string filename)
+ public void Save (string fileName)
{
- Save (filename, SaveOptions.None);
+ Save (fileName, SaveOptions.None);
}
- public void Save (string filename, SaveOptions options)
+ public void Save (string fileName, SaveOptions options)
{
XmlWriterSettings s = new XmlWriterSettings ();
- s.Indent = options != SaveOptions.DisableFormatting;
- using (XmlWriter w = XmlWriter.Create (filename, s)) {
+
+ if ((options & SaveOptions.DisableFormatting) == SaveOptions.None)
+ s.Indent = true;
+#if NET_4_0 || MOONLIGHT || MOBILE
+ if ((options & SaveOptions.OmitDuplicateNamespaces) == SaveOptions.OmitDuplicateNamespaces)
+ s.NamespaceHandling |= NamespaceHandling.OmitDuplicates;
+#endif
+ using (XmlWriter w = XmlWriter.Create (fileName, s)) {
Save (w);
}
}
- public void Save (TextWriter tw)
+ public void Save (TextWriter textWriter)
{
- Save (tw, SaveOptions.None);
+ Save (textWriter, SaveOptions.None);
}
- public void Save (TextWriter tw, SaveOptions options)
+ public void Save (TextWriter textWriter, SaveOptions options)
{
XmlWriterSettings s = new XmlWriterSettings ();
- s.Indent = options != SaveOptions.DisableFormatting;
- using (XmlWriter w = XmlWriter.Create (tw, s)) {
+
+ if ((options & SaveOptions.DisableFormatting) == SaveOptions.None)
+ s.Indent = true;
+#if NET_4_0 || MOONLIGHT || MOBILE
+ if ((options & SaveOptions.OmitDuplicateNamespaces) == SaveOptions.OmitDuplicateNamespaces)
+ s.NamespaceHandling |= NamespaceHandling.OmitDuplicates;
+#endif
+ using (XmlWriter w = XmlWriter.Create (textWriter, s)) {
Save (w);
}
}
- public void Save (XmlWriter w)
+ public void Save (XmlWriter writer)
{
- WriteTo (w);
+ WriteTo (writer);
}
+#if NET_4_0 || MOONLIGHT || MOBILE
+ public void Save (Stream stream)
+ {
+ Save (stream, SaveOptions.None);
+ }
+
+ public void Save (Stream stream, SaveOptions options)
+ {
+ XmlWriterSettings s = new XmlWriterSettings ();
+ if ((options & SaveOptions.DisableFormatting) == SaveOptions.None)
+ s.Indent = true;
+ if ((options & SaveOptions.OmitDuplicateNamespaces) == SaveOptions.OmitDuplicateNamespaces)
+ s.NamespaceHandling |= NamespaceHandling.OmitDuplicates;
+
+ using (var writer = XmlWriter.Create (stream, s)){
+ Save (writer);
+ }
+ }
+#endif
public IEnumerable <XElement> AncestorsAndSelf ()
{
return GetAncestorList (null, true);
void SetAttributeObject (XAttribute a)
{
+ OnAddingObject (a);
a = (XAttribute) XUtil.GetDetachedObject (a);
a.SetOwner (this);
if (attr_first == null) {
a.PreviousAttribute = attr_last;
attr_last = a;
}
+ OnAddedObject (a);
}
- public override void WriteTo (XmlWriter w)
+ string LookupPrefix (string ns, XmlWriter w)
{
- // some people expect the same prefix output as in input,
- // in the loss of performance... see bug #466423.
- string prefix = name.NamespaceName.Length > 0 ? w.LookupPrefix (name.Namespace.NamespaceName) : String.Empty;
+ string prefix = ns.Length > 0 ? GetPrefixOfNamespace (ns) ?? w.LookupPrefix (ns) : String.Empty;
foreach (XAttribute a in Attributes ()) {
- if (a.IsNamespaceDeclaration && a.Value == name.Namespace.NamespaceName) {
+ if (a.IsNamespaceDeclaration && a.Value == ns) {
if (a.Name.Namespace == XNamespace.Xmlns)
prefix = a.Name.LocalName;
// otherwise xmlns="..."
break;
}
}
+ return prefix;
+ }
+
+ static string CreateDummyNamespace (ref int createdNS, IEnumerable<XAttribute> atts, bool isAttr)
+ {
+ if (!isAttr && atts.All (a => a.Name.LocalName != "xmlns" || a.Name.NamespaceName == XNamespace.Xmlns.NamespaceName))
+ return String.Empty;
+ string p = null;
+ do {
+ p = "p" + (++createdNS);
+ // check conflict
+ if (atts.All (a => a.Name.LocalName != p || a.Name.NamespaceName == XNamespace.Xmlns.NamespaceName))
+ break;
+ } while (true);
+ return p;
+ }
+
+ public override void WriteTo (XmlWriter writer)
+ {
+ // some people expect the same prefix output as in input,
+ // in the loss of performance... see bug #466423.
+ string prefix = LookupPrefix (name.NamespaceName, writer);
+ int createdNS = 0;
+ if (prefix == null)
+ prefix = CreateDummyNamespace (ref createdNS, Attributes (), false);
- w.WriteStartElement (prefix, name.LocalName, name.Namespace.NamespaceName);
+ writer.WriteStartElement (prefix, name.LocalName, name.Namespace.NamespaceName);
foreach (XAttribute a in Attributes ()) {
if (a.IsNamespaceDeclaration) {
if (a.Name.Namespace == XNamespace.Xmlns)
- w.WriteAttributeString ("xmlns", a.Name.LocalName, XNamespace.Xmlns.NamespaceName, a.Value);
+ writer.WriteAttributeString ("xmlns", a.Name.LocalName, XNamespace.Xmlns.NamespaceName, a.Value);
else
- w.WriteAttributeString ("xmlns", a.Value);
+ writer.WriteAttributeString ("xmlns", a.Value);
+ } else {
+ string apfix = LookupPrefix (a.Name.NamespaceName, writer);
+ if (apfix == null)
+ apfix = CreateDummyNamespace (ref createdNS, Attributes (), true);
+ writer.WriteAttributeString (apfix, a.Name.LocalName, a.Name.Namespace.NamespaceName, a.Value);
}
- else
- w.WriteAttributeString (a.Name.LocalName, a.Name.Namespace.NamespaceName, a.Value);
}
foreach (XNode node in Nodes ())
- node.WriteTo (w);
+ node.WriteTo (writer);
if (explicit_is_empty)
- w.WriteEndElement ();
+ writer.WriteEndElement ();
else
- w.WriteFullEndElement ();
+ writer.WriteFullEndElement ();
}
public XNamespace GetDefaultNamespace ()
{
for (XElement el = this; el != null; el = el.Parent)
foreach (XAttribute a in el.Attributes ())
- if (a.IsNamespaceDeclaration && a.Name.LocalName == prefix)
+ if (a.IsNamespaceDeclaration && (prefix.Length == 0 && a.Name.LocalName == "xmlns" || a.Name.LocalName == prefix))
return XNamespace.Get (a.Value);
return XNamespace.None; // nothing is declared.
}
yield return a.Name.Namespace == XNamespace.None ? String.Empty : a.Name.LocalName;
}
- public void ReplaceAll (object item)
+ public void ReplaceAll (object content)
{
RemoveNodes ();
- Add (item);
+ Add (content);
}
- public void ReplaceAll (params object [] items)
+ public void ReplaceAll (params object [] content)
{
RemoveNodes ();
- Add (items);
+ Add (content);
}
- public void ReplaceAttributes (object item)
+ public void ReplaceAttributes (object content)
{
RemoveAttributes ();
- Add (item);
+ Add (content);
}
- public void ReplaceAttributes (params object [] items)
+ public void ReplaceAttributes (params object [] content)
{
RemoveAttributes ();
- Add (items);
+ Add (content);
}
public void SetElementValue (XName name, object value)
{
- XElement el = new XElement (name, value);
- RemoveNodes ();
- Add (el);
+ var element = Element (name);
+ if (element == null && value != null) {
+ Add (new XElement (name, value));
+ } else if (element != null && value == null) {
+ element.Remove ();
+ } else
+ element.SetValue (value);
}
public void SetValue (object value)