--- /dev/null
+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;
+ }
+}
+}