Posts Tagged Document Object Model

Replace Xml Node with Raw Xml in .Net

In this post I will simulate a user editing a raw XmlNode from an existing xml document. Say for example we extract the node to edit, with subnodes, and place that in a text box. The user edits the text adding whatever is needed, but keeping with the original nodes, and then signals they are done. Upon that signal we take that raw fragment from the textbox and insert it into the document. Here is the code:

   1: string xmlInitial =
   2: @"<?xml version='1.0'?>
   3: <Rules>
   4:     <OpenBalances function='ReOrderFifo'>
   5:         <column name='SecurityID' used='True'/>
   6:         <column name='COL2' used='False'>#@#</column>
   7:         <column name='COL3' used='False'>#@#</column>
   8:     </OpenBalances>
   9:     <ClosedBalances/>
  10: </Rules>";
  11:
  12: string xmlCreatedByTheUser =
  13: @"<OpenBalances function='ReOrderFifo' iAmNew='true'>
  14:     <column name='SecurityID' used='True'/>
  15:     <column name='COL2' used='False'>#@#</column>
  16:     <column name='COL3' used='False'>#@#</column>
  17: </OpenBalances>";
  18:
  19:     XmlDocument originalXml = new XmlDocument();
  20:
  21:     string targetNode = "descendant::*[name(.) ='OpenBalances']";
  22:
  23:     originalXml.LoadXml(xmlInitial);
  24:
  25:     // Simulate the selection of the subnode
  26:     // for the user to edit in the first nodes
  27:     // Rules.
  28:     XmlNode editNode = originalXml.SelectSingleNode(targetNode);
  29:
  30:     // Get a fragment and slide the changed data into it.
  31:     XmlDocumentFragment fragment = originalXml.CreateDocumentFragment();
  32:     fragment.InnerXml = xmlCreatedByTheUser;
  33:
  34:     // Replace the contents of the editNode with the user fragment.
  35:     editNode.ParentNode.ReplaceChild(fragment, editNode);
  36:
  37:     Console.WriteLine(originalXml.OuterXml);
  • Line 01: This is our original Xml which we will use.
  • Line 12: This is the simulated change by the user. The user adds one attribute iAmNew.
  • Line 21: We will use this Xpath to extract the node to work on for the user.
  • Line 23: We load the initial Xml into the document.
  • Line 28: Simulated extraction of the node to display to the user.
  • Line 31: Its important that we create a Xml fragment from our original XmlDocument. We could not prune another XmlDocument, or create a fragment on the fly, it must come from the original Xml.
  • Line 32: Simulated user change and loading from a TextBox.
  • Line 35: Do the replacement here.
  • Line 37: Output the Xml.

Console Output:

   1: <?xml version="1.0"?>
   2: <Rules>
   3:    <OpenBalances function="ReOrderFifo" iAmNew="true">
   4:        <column name="SecurityID" used="True" />
   5:        <column name="COL2" used="False">##@##</column>
   6:        <column name="COL3" used="False">##@##</column>
   7:    </OpenBalances>
   8:    <ClosedBalances />
   9: </Rules>
Share

Tags:

Add Attribute to XmlDocument in .Net

Here is an example of adding an attribute to an XmlDocument in C# and .Net. The below code reads in Xml. Where there are nodes that do not contain and ID attribute, we will add that attribute using the name as the value.

 1: public static string xmlAcct =
 2: @"<?xml version='1.0' encoding='utf-8'?>
 3: <Accounts>
 4: <acct acct='aex113' country_code='us' name='abcde' />
 5: <acct acct='aex114' name='eeaad' country_code='us' />
 6: <acct acct='aex115' country_code='us' name='eoo' id='eoo9' />
 7: </Accounts>
 8: ";
 9:
 10: public static void AddAttribute()
 11: {
 12:
 13:     XmlDocument originalXml = new XmlDocument();
 14:
 15:
 16:     originalXml.LoadXml(xmlAcct);
 17:
 18:     XmlNodeList accts
 19:        = originalXml.SelectNodes("descendant::*[name(.) ='acct']");
 20:     XmlNode temp;
 21:     XmlNode name;
 22:     XmlAttribute attr;
 23:
 24:     foreach (XmlNode current in accts)
 25:     {
 26:         temp = current.SelectSingleNode("@id");
 27:         if (temp == null)
 28:         {
 29:             name = current.SelectSingleNode("@name");
 30:             if (name != null)
 31:             {
 32:                 attr = originalXml.CreateAttribute("id");
 33:                 attr.InnerText = name.InnerText;
 34:                 current.Attributes.Append(attr);
 35:             }
 36:         }
 37:
 38:     }
 39:
 40:     Console.WriteLine(originalXml.OuterXml);
 41:
 42:
 43: }
  • Line 01: Create Test XMl
  • Line 16: Load the test Xml.
  • Line 19: Get all the account nodes using Xpath.
  • Line 24: Work through each account node to add an attribute if ID does not exist.
  • Line 27: When null we need to add the ID node.
  • Line 29: We will use the name as the ID.
  • Line 32: We have to create the attribute off of the current node. Very important, for we can’t just slap any old node on. It has to be from the current branch/node.
  • Line 40: Display the changes.
Share

Tags: ,

Xml handling using XmlDocument and Xpath

This is a quick example of loading data into and XmlDocument and then extracting data using XPath. Each of those topics have books written on them and one can surely use this sample as a starting point for that learning.

Note the Xpath used does not demonstate the full capabilities of Xpath such as one can extract attributes off of nodes using the @ sign.

 1: XmlDocument xd = new XmlDocument();
 2:
 3: xd.LoadXml(
 4: @"<?xml version='1.0'?>
 5:     <Wrapper>
 6:         <myData>some stuff</myData>
 7:         <level access='t'>4</level>
 8:         <size>medium</size>
 9:    </Wrapper>");
 10:
 11: XmlNode node
 12:     = xd.SelectSingleNode(
 13:         "descendant::*[name(.) ='myData']");
 14:
 15: Console.WriteLine("Inner Text ({0}) Outer Xml {1}",
 16:                   node.InnerText,
 17:                   node.OuterXml);
 18:
  • Line 1 Create a new XmlDocument.
  • Line 3 Load the Xml from a string, other ways one could load from a file.
  • Line 11-13 We are interested in getting the first node encountered thats name is myData. By using the SelectSingleNode we can get just one.
  • Line 13 This is a generic Xpath that I like to use which can get information from the current node looked being looked at. What it is saying is, Looking at all the decendants of the current node, give me the node where the name found is myData.
  • Line 15 We are not checking to see if node is null. In normal code this is a no-no, check before usage!
  • Line 16 The actual data is store in the InnerText of the node, which we will extract.
  • Line 17 Sometimes we need the xml along with it, see below.

This is what the output looks like:

Inner Text (some stuff) Outer Xml <myData>some stuff</myData>

Share

Tags: ,