]> wagnertech.de Git - mDoc.git/blobdiff - csharp/mutil/XmlExtractor.cs
csharp-s6ts
[mDoc.git] / csharp / mutil / XmlExtractor.cs
diff --git a/csharp/mutil/XmlExtractor.cs b/csharp/mutil/XmlExtractor.cs
new file mode 100644 (file)
index 0000000..f8bdb51
--- /dev/null
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace mutil {
+
+public class XmlExtractor {
+       public const int EC_BEG = 1; // begin of subtree (current node descends) - in
+       public const int EC_CTN = 2; // continue with next sibling element - in / out: data of found element 
+       public const int EC_END = 3; // subtree completion (current node ascends); no data - out
+
+
+       private XmlDocument docNode;
+       private bool textMode;
+       public XmlNode CurrentNode;
+
+       public XmlExtractor(object BaseNode = null, bool TextMode = false) {
+               this.CurrentNode = (XmlNode)BaseNode;
+               this.textMode = TextMode;
+       }
+       
+       public void openInput(string input){
+               this.docNode = new XmlDocument();
+               this.docNode.Load(input);
+               this.CurrentNode = this.docNode;
+       }
+       
+       public void toTop(){
+               this.CurrentNode = this.docNode;
+       }
+       public void toParent(){
+               this.CurrentNode = this.CurrentNode.ParentNode;
+       }
+       public int extractElement(int extr_ctl, out string elem, out string value, out Dictionary<string,string> attrs) { 
+               elem  = "";
+               value = null;
+               attrs = new Dictionary<string,string>();
+
+               XmlNode srh_node;
+               
+               if (extr_ctl == EC_BEG) {
+                       srh_node = this.CurrentNode.FirstChild;
+               } else if (extr_ctl == EC_CTN) {
+                       srh_node = this.CurrentNode.NextSibling;
+               } else {
+                       return EC_END;
+               }
+
+               // search for next element node
+               if (! this.textMode) {
+                       while (srh_node != null) {
+                               if (srh_node.NodeType != XmlNodeType.Element) {
+                                       srh_node = srh_node.NextSibling;
+                               } else {
+                                       break;
+                               }
+                       }
+               }
+                               
+               if (srh_node != null) {
+                       // element node found: extract tag name, value and attributes
+                   this.CurrentNode = srh_node;
+                   this.getCurrentNodeData(out elem, out value, out attrs);
+                       return EC_CTN;
+               } else {
+                       // terminate / ascend subtree after child extraction
+                       if (extr_ctl == EC_CTN) {
+                               this.CurrentNode = this.CurrentNode.ParentNode;
+                       }
+                       return EC_END;
+               }
+               
+       }
+       public void getCurrentNodeData(out string elem, out string value, out Dictionary<string,string> attrs) {
+           elem = this.CurrentNode.Name;
+               value = null;
+               attrs = new Dictionary<string,string>();
+               if (this.textMode) {
+                       if (this.CurrentNode.NodeType == XmlNodeType.Text) value = this.CurrentNode.Value;
+               }
+               else {
+                       if (this.CurrentNode.InnerText != null) value = this.CurrentNode.InnerText;
+               }
+               if (this.CurrentNode.Attributes != null) {
+                       for (int att_idx = 0; att_idx < this.CurrentNode.Attributes.Count; att_idx++) {
+                               var att_node = this.CurrentNode.Attributes[att_idx];
+                               attrs[att_node.Name] = this.CurrentNode.Attributes[att_idx].Value;
+                       }
+               }
+       }
+       public XmlNode gotoChild(string name) {
+          // return True/False, if child node could be found
+          int cntl = EC_BEG;
+          string elem;
+          string value;
+          Dictionary<string,string> attrs;
+          while ((cntl = this.extractElement(cntl, out elem, out value, out attrs)) != EC_END) {
+              if (elem == name) return this.CurrentNode;
+          }
+          return null;
+       }
+       public XmlNode requireChild(string name) {
+          // throws exception, if child not present
+          XmlNode child = this.gotoChild(name);
+          if (child == null) throw new Exception("Could not find node "+name);
+          return child;
+       }
+}
+}