Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
With the rules engine you can't directly add a node to an XML document in a rules action. On the other time you often would like to do that. No worries, you can call a helper class to do the work for you. Here is an example helper class from John Rummell <welcome back> that does the trick. Nothing particularly revolutionary in the code but it will save you some time I'm sure.
using System;
using System.Xml;
using Microsoft.RuleEngine;
namespace XMLHelpers
{
/// <summary>
/// Class used to add nodes and/or attributes to a TypedXmlDocument
///
/// Using the example:
/// <root>
/// <a>
/// </a>
/// </root>
///
/// AddNode(doc, "/root/a", "b") or AddNodeIfNotThere(doc, "/root/a", "b") will result in:
/// <root>
/// <a>
/// <b />
/// </a>
/// </root>
///
/// AddAttribute(doc, "//a", "name", "value") will result in:
/// <root>
/// <a name="value">
/// </a>
/// </root>
///
/// The code does not create intermediate nodes (e.g. can't create a "c" inside "b"
/// if "b" doesn't exist. As a result, you need to sequence the calls:
/// AddNode(doc, "/root/a", "b");
/// AddNode(doc, "/root/a/b", "c");
/// Note that if "b" already exists, a second "b" node will be created. Use AddNodeIfNotThere
/// to create the node "b" if it doesn't already exist, but leave it alone if it is.
/// </summary>
public class XmlCreateNodes
{
/// <summary>
/// Add an attribute with a specified name and value into the node selected by the XPath
/// </summary>
/// <param name="txd">RuleEngine wrapper for an XmlDocument (or some part of it)</param>
/// <param name="xPath">XPath that must select a node (null or "" to use current node)</param>
/// <param name="attributeName">Attribute name</param>
/// <param name="attributeValue">Attribute value</param>
public void AddAttribute(TypedXmlDocument txd, string xPath, string attributeName, string attributeValue)
{
// can we find the XPath indicated?
// we need an XmlElement in order to set the attribute, not the usual XmlNode
// if the result is not an XmlElement, we don't work
XmlElement node = LocateXPath(txd, xPath) as XmlElement;
// if we found a matching node, add the attribute
if (null != node)
{
node.SetAttribute(attributeName, attributeValue);
}
}
/// <summary>
/// Add an new node with a specified name and namespace into the node selected by the XPath
/// </summary>
/// <param name="txd">RuleEngine wrapper for an XmlDocument (or some part of it)</param>
/// <param name="xPath">XPath that must select a node (null or "" to use current node)</param>
/// <param name="nodeName">Name for the new node</param>
/// <param name="nodeNamespace">Namespace for the new node</param>
public void AddNode(TypedXmlDocument txd, string xPath, string nodeName, string nodeNamespace)
{
// can we find the XPath indicated?
XmlNode node = LocateXPath(txd, xPath);
if (null == node) return;
// determine the root node for the document
// if the XPath selects the TXD, it will have no root if it is an XmlDocument
// in that case, simply use the document from the TXD
XmlDocument root = node.OwnerDocument;
if (null == root)
{
// if the XPath selects the TXD, it may
// so fix accordingly
root = txd.Document as XmlDocument;
if (null == root) return;
}
// create a new node and add it in
XmlElement newNode = root.CreateElement(nodeName, nodeNamespace);
node.AppendChild(newNode);
}
/// <summary>
/// Add an new node with a specified name into the node selected by the XPath
/// </summary>
/// <param name="txd">RuleEngine wrapper for an XmlDocument (or some part of it)</param>
/// <param name="xPath">XPath that must select a node (null or "" to use current node)</param>
/// <param name="nodeName">Name for the new node</param>
public void AddNode(TypedXmlDocument txd, string xPath, string nodeName)
{
// can we find the XPath indicated?
XmlNode node = LocateXPath(txd, xPath);
if (null == node) return;
// determine the root node for the document
// if the XPath selects the TXD, it will have no root if it is an XmlDocument
// in that case, simply use the document from the TXD
XmlDocument root = node.OwnerDocument;
if (null == root)
{
// if the XPath selects the TXD, it may
// so fix accordingly
root = txd.Document as XmlDocument;
if (null == root) return;
}
// create a new node and add it in
XmlElement newNode = root.CreateElement(nodeName);
node.AppendChild(newNode);
}
/// <summary>
/// Add an new node with a specified name and namespace into the node selected by the XPath
/// provided that it doesn't already exist
/// </summary>
/// <param name="txd">RuleEngine wrapper for an XmlDocument (or some part of it)</param>
/// <param name="xPath">XPath that must select a node (null or "" to use current node)</param>
/// <param name="nodeName">Name for the new node</param>
/// <param name="nodeNamespace">Namespace for the new node</param>
public void AddNodeIfNotThere(TypedXmlDocument txd, string xPath, string nodeName, string nodeNamespace)
{
// can we find the XPath indicated?
XmlNode node = LocateXPath(txd, xPath);
if (null == node) return;
// does the new element already exist?
foreach (XmlNode child in node.ChildNodes)
{
if ((child.LocalName == nodeName) && (child.NamespaceURI == nodeNamespace)) return;
}
// determine the root node for the document
// if the XPath selects the TXD, it will have no root if it is an XmlDocument
// in that case, simply use the document from the TXD
XmlDocument root = node.OwnerDocument;
if (null == root)
{
// if the XPath selects the TXD, it may
// so fix accordingly
root = txd.Document as XmlDocument;
if (null == root) return;
}
// create a new node and add it in
XmlElement newNode = root.CreateElement(nodeName, nodeNamespace);
node.AppendChild(newNode);
}
/// <summary>
/// Add an new node with a specified name into the node selected by the XPath
/// provided that it doesn't already exist
/// </summary>
/// <param name="txd">RuleEngine wrapper for an XmlDocument (or some part of it)</param>
/// <param name="xPath">XPath that must select a node (null or "" to use current node)</param>
/// <param name="nodeName">Name for the new node</param>
public void AddNodeIfNotThere(TypedXmlDocument txd, string xPath, string nodeName)
{
// can we find the XPath indicated?
XmlNode node = LocateXPath(txd, xPath);
if (null == node) return;
// does the new element already exist?
foreach (XmlNode child in node.ChildNodes)
{
if (child.LocalName == nodeName) return;
}
// determine the root node for the document
// if the XPath selects the TXD, it will have no root if it is an XmlDocument
// in that case, simply use the document from the TXD
XmlDocument root = node.OwnerDocument;
if (null == root)
{
// if the XPath selects the TXD, it may
// so fix accordingly
root = txd.Document as XmlDocument;
if (null == root) return;
}
// create a new node and add it in
XmlElement newNode = root.CreateElement(nodeName);
node.AppendChild(newNode);
}
/// <summary>
/// Select the first node that the specified XPath points to inside the XmlDocument
/// </summary>
/// <param name="txd">RuleEngine wrapper for an XmlDocument (or some part of it)</param>
/// <param name="xPath">XPath that must select a node (null or "" to use current node)</param>
/// <returns></returns>
internal XmlNode LocateXPath(TypedXmlDocument txd, string xPath)
{
// does the TXD contain a node?
XmlNode parent = txd.Document;
if (null == parent) return null;
// is there an XPath specified? if not, return the parent
if ((xPath == null) || (xPath == string.Empty)) return parent;
// return the first node that the XPath points to
return parent.SelectSingleNode(xPath, txd.NamespaceManager);
}
}
}
Comments
- Anonymous
January 21, 2009
PingBack from http://www.keyongtech.com/322562-add-a-new-field-element