diff --git a/src/HtmlAgilityPack.Shared/HtmlNode.cs b/src/HtmlAgilityPack.Shared/HtmlNode.cs
index 5fb4313..7c7fa04 100644
--- a/src/HtmlAgilityPack.Shared/HtmlNode.cs
+++ b/src/HtmlAgilityPack.Shared/HtmlNode.cs
@@ -756,10 +756,28 @@ public static bool CanOverlapElement(string name)
/// The HTML text.
/// The newly created node instance.
public static HtmlNode CreateNode(string html)
+ {
+ return CreateNode(html, null);
+ }
+
+ ///
+ /// Creates an HTML node from a string representing literal HTML.
+ ///
+ /// The HTML text.
+ /// The HTML Document builder.
+ /// The newly created node instance.
+ public static HtmlNode CreateNode(string html, Action htmlDocumentBuilder)
{
// REVIEW: this is *not* optimum...
HtmlDocument doc = new HtmlDocument();
+
+ if (htmlDocumentBuilder != null)
+ {
+ htmlDocumentBuilder(doc);
+ }
+
doc.LoadHtml(html);
+
if (!doc.DocumentNode.IsSingleElementNode())
{
throw new Exception("Multiple node elments can't be created.");
@@ -1447,20 +1465,11 @@ public T GetAttributeValue(string name, T def)
{
return def;
}
-
- TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
- try
- {
- if (converter != null && converter.CanConvertTo(att.Value.GetType()))
- {
- return (T)converter.ConvertTo(att.Value, typeof(T));
- }
- else
- {
- return (T) (object) att.Value;
- }
- }
+ try
+ {
+ return (T)att.Value.To(typeof(T));
+ }
catch
{
return def;
@@ -1659,6 +1668,61 @@ public void RemoveAllIDforNode(HtmlNode node)
}
}
+ /// Move a node already associated and append it to this node instead.
+ /// The child node to move.
+ public void MoveChild(HtmlNode child)
+ {
+ if (child == null)
+ {
+ throw new ArgumentNullException($"Oops! the '{nameof(child)}' parameter cannot be null.");
+ }
+
+ var oldParent = child.ParentNode;
+
+ AppendChild(child);
+
+ if (oldParent != null)
+ {
+ oldParent.RemoveChild(child);
+ }
+ }
+
+ /// Move a children collection already associated and append it to this node instead.
+ /// The children collection already associated to move to another node.
+ public void MoveChildren(HtmlNodeCollection children)
+ {
+ if (children == null)
+ {
+ throw new ArgumentNullException($"Oops! the '{nameof(children)}' parameter cannot be null.");
+ }
+
+ var oldParent = children.ParentNode;
+
+ AppendChildren(children);
+
+ if (oldParent != null)
+ {
+ oldParent.RemoveChildren(children);
+ }
+ }
+
+ /// Removes the children collection for this node.
+ /// The old children collection to remove.
+ public void RemoveChildren(HtmlNodeCollection oldChildren)
+ {
+ if (oldChildren == null)
+ {
+ throw new ArgumentNullException($"Oops! the '{nameof(oldChildren)}' parameter cannot be null.");
+ }
+
+ var list = oldChildren.ToList();
+
+ foreach (HtmlNode newChild in list)
+ {
+ RemoveChild(newChild);
+ }
+ }
+
///
/// Removes the specified child node.
///
diff --git a/src/HtmlAgilityPack.Shared/HtmlNodeCollection.cs b/src/HtmlAgilityPack.Shared/HtmlNodeCollection.cs
index 43df9a2..8a04636 100644
--- a/src/HtmlAgilityPack.Shared/HtmlNodeCollection.cs
+++ b/src/HtmlAgilityPack.Shared/HtmlNodeCollection.cs
@@ -38,6 +38,15 @@ public HtmlNodeCollection(HtmlNode parentnode)
#region Properties
+ /// Gets the parent node associated to the collection.
+ internal HtmlNode ParentNode
+ {
+ get
+ {
+ return _parentnode;
+ }
+ }
+
///
/// Gets a given node from the list.
///
diff --git a/src/HtmlAgilityPack.Shared/Utilities.cs b/src/HtmlAgilityPack.Shared/Utilities.cs
index e3bdec9..e515197 100644
--- a/src/HtmlAgilityPack.Shared/Utilities.cs
+++ b/src/HtmlAgilityPack.Shared/Utilities.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
namespace HtmlAgilityPack
{
@@ -19,5 +20,45 @@ internal static class Utilities
return defaultValue;
return value;
}
+
+#if !(METRO || NETSTANDARD1_3 || NETSTANDARD1_6)
+ internal static object To(this Object @this, Type type)
+ {
+ if (@this != null)
+ {
+ Type targetType = type;
+
+ if (@this.GetType() == targetType)
+ {
+ return @this;
+ }
+
+ TypeConverter converter = TypeDescriptor.GetConverter(@this);
+ if (converter != null)
+ {
+ if (converter.CanConvertTo(targetType))
+ {
+ return converter.ConvertTo(@this, targetType);
+ }
+ }
+
+ converter = TypeDescriptor.GetConverter(targetType);
+ if (converter != null)
+ {
+ if (converter.CanConvertFrom(@this.GetType()))
+ {
+ return converter.ConvertFrom(@this);
+ }
+ }
+
+ if (@this == DBNull.Value)
+ {
+ return null;
+ }
+ }
+
+ return @this;
+ }
+#endif
}
}
\ No newline at end of file