1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * Copyright (c) 2003-2012 by AG-Software * 3 * All Rights Reserved. * 4 * Contact information for AG-Software is available at http://www.ag-software.de * 5 * * 6 * Licence: * 7 * The agsXMPP SDK is released under a dual licence * 8 * agsXMPP can be used under either of two licences * 9 * * 10 * A commercial licence which is probably the most appropriate for commercial * 11 * corporate use and closed source projects. * 12 * * 13 * The GNU Public License (GPL) is probably most appropriate for inclusion in * 14 * other open source projects. * 15 * * 16 * See README.html for details. * 17 * * 18 * For general enquiries visit our website at: * 19 * http://www.ag-software.de * 20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 21 22 using System; 23 using System.Collections.Generic; 24 using System.Collections.Specialized; 25 using System.Globalization; 26 using System.Text; 27 using System.IO; 28 using System.Xml; 29 30 namespace agsXMPP.Xml.Dom 31 { 32 33 public class Element : Node 34 { 35 // Member Variables 36 private string m_TagName; 37 private string m_Prefix; 38 private ListDictionary m_Attributes; 39 private Text m_Value = new Text(); 40 Element()41 public Element() 42 { 43 NodeType = NodeType.Element; 44 AddChild(m_Value); 45 46 m_Attributes = new ListDictionary(); 47 48 m_TagName = ""; 49 Value = ""; 50 } 51 Element(string tagName)52 public Element(string tagName) :this() 53 { 54 m_TagName = tagName; 55 } 56 Element(string tagName, string tagText)57 public Element(string tagName, string tagText) : this(tagName) 58 { 59 Value = tagText; 60 } 61 Element(string tagName, bool tagText)62 public Element(string tagName, bool tagText) : this(tagName, tagText ? "true" : "false") 63 { 64 } 65 Element(string tagName, string tagText, string ns)66 public Element(string tagName, string tagText, string ns) : this(tagName, tagText) 67 { 68 Namespace = ns; 69 } 70 71 /// <summary> 72 /// Is this Element a Rootnode? 73 /// </summary> 74 public bool IsRootElement 75 { 76 get 77 { 78 return (Parent != null ? false : true); 79 } 80 } 81 82 public override string Value 83 { 84 get { return m_Value.Value; } 85 set { m_Value.Value = value; } 86 } 87 88 public string Prefix 89 { 90 get { return m_Prefix; } 91 set { m_Prefix = value; } 92 } 93 94 /// <summary> 95 /// The Full Qualified Name 96 /// </summary> 97 public string TagName 98 { 99 get { return m_TagName; } 100 set { m_TagName = value; } 101 } 102 103 public string TextBase64 104 { 105 get 106 { 107 byte[] b = Convert.FromBase64String(Value); 108 return Encoding.ASCII.GetString(b, 0, b.Length); 109 } 110 set 111 { 112 byte[] b = Encoding.UTF8.GetBytes(value); 113 //byte[] b = Encoding.Default.GetBytes(value); 114 Value = Convert.ToBase64String(b, 0, b.Length); 115 } 116 } 117 118 public ListDictionary Attributes 119 { 120 get { return m_Attributes; } 121 } 122 GetAttributeEnum(string name, Type enumType)123 public object GetAttributeEnum(string name, Type enumType) 124 { 125 string att = GetAttribute(name); 126 if ((att == null)) 127 return -1; 128 try 129 { 130 #if CF 131 return util.Enum.Parse(enumType, att, true); 132 #else 133 return Enum.Parse(enumType, att, true); 134 #endif 135 } 136 catch (Exception) 137 { 138 return -1; 139 } 140 } 141 GetAttribute(string name)142 public string GetAttribute(string name) 143 { 144 if (HasAttribute(name)) 145 return (string) m_Attributes[name]; 146 return null; 147 } 148 GetAttributeInt(string name)149 public int GetAttributeInt(string name) 150 { 151 if (HasAttribute(name)) 152 { 153 return int.Parse((string) m_Attributes[name]); 154 } 155 return 0; 156 } 157 GetAttributeLong(string name)158 public long GetAttributeLong(string name) 159 { 160 if (HasAttribute(name)) 161 { 162 return long.Parse((string) m_Attributes[name]); 163 } 164 return 0; 165 } 166 167 /// <summary> 168 /// Reads a boolean Attribute, if the attrib is absent it returns also false. 169 /// </summary> 170 /// <param name="name"></param> 171 /// <returns></returns> GetAttributeBool(string name)172 public bool GetAttributeBool(string name) 173 { 174 if (HasAttribute(name)) 175 { 176 string tmp = (string) m_Attributes[name]; 177 if (tmp.ToLower() == "true") 178 return true; 179 return false; 180 } 181 return false; 182 } 183 GetAttributeJid(string name)184 public Jid GetAttributeJid(string name) 185 { 186 if (HasAttribute(name)) 187 return new Jid(this.GetAttribute(name)); 188 return null; 189 } 190 191 /// <summary> 192 /// 193 /// </summary> 194 /// <param name="name"></param> 195 /// <param name="ifp"></param> 196 /// <returns></returns> GetAttributeDouble(string name, IFormatProvider ifp)197 public double GetAttributeDouble(string name, IFormatProvider ifp) 198 { 199 if (HasAttribute(name)) 200 { 201 try 202 { 203 return double.Parse((string)m_Attributes[name], ifp); 204 } 205 catch 206 { 207 return double.NaN; 208 } 209 } 210 return double.NaN; 211 } 212 213 /// <summary> 214 /// Get a Attribute of type double (Decimal seperator = ".") 215 /// </summary> 216 /// <param name="name"></param> 217 /// <returns></returns> GetAttributeDouble(string name)218 public double GetAttributeDouble(string name) 219 { 220 // Parse the double always in english format ==> "." = Decimal seperator 221 NumberFormatInfo nfi = new NumberFormatInfo(); 222 nfi.NumberGroupSeparator = "."; 223 return GetAttributeDouble(name, nfi); 224 } 225 HasAttribute(string name)226 public bool HasAttribute(string name) 227 { 228 return Attributes.Contains(name); 229 } 230 231 /// <summary> 232 /// Return the Text of the first Tag with a specified Name. 233 /// It doesnt traverse the while tree and checks only the unerlying childnodes 234 /// </summary> 235 /// <param name="TagName">Name of Tag to find as string</param> 236 /// <returns></returns> GetTag(string TagName)237 public string GetTag(string TagName) 238 { 239 Element tag = this._SelectElement(this, TagName); 240 if ( tag != null) 241 return tag.Value; 242 return null; 243 } 244 GetTag(string TagName, bool traverseChildren)245 public string GetTag(string TagName, bool traverseChildren) 246 { 247 Element tag = this._SelectElement(this, TagName, traverseChildren); 248 if ( tag != null) 249 return tag.Value; 250 return null; 251 } 252 GetTag(System.Type type)253 public string GetTag(System.Type type) 254 { 255 Element tag = this._SelectElement(this, type); 256 if ( tag != null) 257 return tag.Value; 258 return null; 259 } 260 GetTagBase64(string TagName)261 public string GetTagBase64(string TagName) 262 { 263 byte[] b = Convert.FromBase64String(GetTag(TagName)); 264 return Encoding.ASCII.GetString(b, 0, b.Length); 265 } 266 267 /// <summary> 268 /// Adds a Tag and encodes the Data to BASE64 269 /// </summary> 270 /// <param name="argTagname"></param> 271 /// <param name="argText"></param> SetTagBase64(string argTagname, string argText)272 public void SetTagBase64(string argTagname, string argText) 273 { 274 byte[] b = Encoding.Unicode.GetBytes(argText); 275 SetTag(argTagname, Convert.ToBase64String(b, 0, b.Length)); 276 } 277 278 /// <summary> 279 /// Adds a Tag end decodes the byte buffer to BASE64 280 /// </summary> 281 /// <param name="argTagname"></param> 282 /// <param name="buffer"></param> SetTagBase64(string argTagname, byte[] buffer)283 public void SetTagBase64(string argTagname, byte[] buffer) 284 { 285 SetTag(argTagname, Convert.ToBase64String(buffer, 0, buffer.Length)); 286 } 287 SetTag(string argTagname, string argText)288 public void SetTag(string argTagname, string argText) 289 { 290 if (HasTag(argTagname) == false) 291 AddChild(new Element(argTagname, argText)); 292 else 293 SelectSingleElement(argTagname).Value = argText; 294 } 295 SetTag(Type type, string argText)296 public void SetTag(Type type, string argText) 297 { 298 if (HasTag(type) == false) 299 { 300 Element newel; 301 newel = (Element) Activator.CreateInstance(type); 302 newel.Value = argText; 303 AddChild(newel); 304 } 305 else 306 SelectSingleElement(type).Value = argText; 307 } 308 SetTag(Type type)309 public void SetTag(Type type) 310 { 311 if (HasTag(type)) 312 RemoveTag(type); 313 314 AddChild( (Element) Activator.CreateInstance(type) ); 315 } 316 SetTag(string argTagname)317 public void SetTag(string argTagname) 318 { 319 SetTag(argTagname, ""); 320 } 321 SetTag(string argTagname, string argText, string argNS)322 public void SetTag(string argTagname, string argText, string argNS) 323 { 324 if (HasTag(argTagname) == false) 325 AddChild(new Element(argTagname, argText, argNS)); 326 else 327 { 328 Element e = SelectSingleElement(argTagname); 329 e.Value = argText; 330 e.Namespace = argNS; 331 } 332 } 333 SetTag(string argTagname, double dbl, IFormatProvider ifp)334 public void SetTag(string argTagname, double dbl, IFormatProvider ifp) 335 { 336 SetTag(argTagname, dbl.ToString(ifp)); 337 } 338 SetTag(string argTagname, double dbl)339 public void SetTag(string argTagname, double dbl) 340 { 341 NumberFormatInfo nfi = new NumberFormatInfo(); 342 nfi.NumberGroupSeparator = "."; 343 SetTag(argTagname, dbl, nfi); 344 } 345 SetTag(string argTagname, bool val)346 public void SetTag(string argTagname, bool val) 347 { 348 SetTag(argTagname, val ? "true" : "false"); 349 } 350 SetTag(string argTagname, int val)351 public void SetTag(string argTagname, int val) 352 { 353 SetTag(argTagname, val.ToString()); 354 } 355 SetTag(string argTagname, Jid jid)356 public void SetTag(string argTagname, Jid jid) 357 { 358 SetTag(argTagname, jid.ToString()); 359 } 360 AddTag(string argTagname, string argText)361 public void AddTag(string argTagname, string argText) 362 { 363 AddChild(new Element(argTagname, argText)); 364 } 365 AddTag(string argTagname)366 public void AddTag(string argTagname) 367 { 368 AddChild(new Element(argTagname)); 369 } 370 GetTagEnum(string name, System.Type enumType)371 public object GetTagEnum(string name, System.Type enumType) 372 { 373 string tag = this.GetTag(name); 374 if ( (tag == null) || (tag.Length == 0) ) 375 return -1; 376 try 377 { 378 #if CF 379 return util.Enum.Parse(enumType, tag, true); 380 #else 381 return Enum.Parse(enumType, tag, true); 382 #endif 383 } 384 catch (Exception) 385 { 386 return -1; 387 } 388 } 389 390 /// <summary> 391 /// Return the Text of the first Tag with a specified Name in all childnodes as boolean 392 /// </summary> 393 /// <param name="TagName">name of Tag to findas string</param> 394 /// <returns></returns> GetTagBool(string TagName)395 public bool GetTagBool(string TagName) 396 { 397 Element tag = this._SelectElement(this, TagName); 398 if ( tag != null) 399 { 400 if (tag.Value.ToLower() == "false" || tag.Value.ToLower() == "0") 401 { 402 return false; 403 } 404 if(tag.Value.ToLower() == "true" || tag.Value.ToLower() == "1") 405 { 406 return true; 407 } 408 return false; 409 } 410 return false; 411 } 412 GetTagInt(string TagName)413 public int GetTagInt(string TagName) 414 { 415 Element tag = _SelectElement(this, TagName); 416 if ( tag != null) 417 return int.Parse(tag.Value); 418 return 0; 419 } 420 421 GetTagJid(string TagName)422 public Jid GetTagJid(string TagName) 423 { 424 string jid = GetTag(TagName); 425 426 if (jid != null) 427 return new Jid(jid); 428 return null; 429 } 430 431 432 /// <summary> 433 /// Get a Tag of type double (Decimal seperator = ".") 434 /// </summary> 435 /// <param name="TagName"></param> 436 /// <returns></returns> GetTagDouble(string argTagName)437 public double GetTagDouble(string argTagName) 438 { 439 // Parse the double always in english format ==> "." = Decimal seperator 440 NumberFormatInfo nfi = new NumberFormatInfo(); 441 nfi.NumberGroupSeparator = "."; 442 443 return GetTagDouble(argTagName, nfi); 444 } 445 446 /// <summary> 447 /// Get a Tag of type double with the given iFormatProvider 448 /// </summary> 449 /// <param name="TagName"></param> 450 /// <param name="nfi"></param> 451 /// <returns></returns> GetTagDouble(string argTagName, IFormatProvider ifp)452 public double GetTagDouble(string argTagName, IFormatProvider ifp) 453 { 454 string val = GetTag(argTagName); 455 if (val != null) 456 return Double.Parse(val, ifp); 457 return Double.NaN; 458 } 459 HasTag(string name)460 public bool HasTag(string name) 461 { 462 Element tag = _SelectElement(this, name); 463 if ( tag != null) 464 return true; 465 return false; 466 } 467 HasTag(string name, bool traverseChildren)468 public bool HasTag(string name, bool traverseChildren) 469 { 470 Element tag = _SelectElement(this, name, traverseChildren); 471 if ( tag != null) 472 return true; 473 return false; 474 } 475 HasTag(Type type)476 public bool HasTag(Type type) 477 { 478 Element tag = _SelectElement(this, type); 479 if ( tag != null) 480 return true; 481 return false; 482 } 483 484 public bool HasTag<T>() where T : Element 485 { 486 return SelectSingleElement<T>() != null; 487 } 488 489 public bool HasTagt<T>(bool traverseChildren) where T : Element 490 { 491 return SelectSingleElement<T>(traverseChildren) != null; 492 } 493 494 HasTag(Type type, bool traverseChildren)495 public bool HasTag(Type type, bool traverseChildren) 496 { 497 Element tag = this._SelectElement(this, type, traverseChildren); 498 if ( tag != null) 499 return true; 500 return false; 501 } 502 503 /// <summary> 504 /// 505 /// </summary> 506 /// <param name="enumType"></param> 507 /// <returns></returns> HasTagEnum(Type enumType)508 public object HasTagEnum(Type enumType) 509 { 510 #if CF || CF_2 511 string[] members = Util.Enum.GetNames(enumType); 512 #else 513 string[] members = Enum.GetNames(enumType); 514 #endif 515 foreach (string member in members) 516 { 517 if (HasTag(member)) 518 #if CF 519 return util.Enum.Parse(enumType, member, false); 520 #else 521 return Enum.Parse(enumType, member, false); 522 #endif 523 } 524 return -1; 525 } 526 527 /// <summary> 528 /// Remove a Tag when it exists 529 /// </summary> 530 /// <param name="TagName">Tagname to remove</param> 531 /// <returns>true when existing and removed, false when not existing</returns> RemoveTag(string TagName)532 public bool RemoveTag(string TagName) 533 { 534 Element tag = _SelectElement(this, TagName); 535 if ( tag != null) 536 { 537 tag.Remove(); 538 return true; 539 } 540 return false; 541 } 542 543 /// <summary> 544 /// Remove a Tag when it exists 545 /// </summary> 546 /// <param name="type">Type of the tag that should be removed</param> 547 /// <returns>true when existing and removed, false when not existing</returns> RemoveTag(Type type)548 public bool RemoveTag(Type type) 549 { 550 Element tag = _SelectElement(this, type); 551 if (tag != null) 552 { 553 tag.Remove(); 554 return true; 555 } 556 557 return false; 558 } 559 560 public bool RemoveTag<T>() where T : Element 561 { 562 Element tag = SelectSingleElement<T>(); 563 if (tag != null) 564 { 565 tag.Remove(); 566 return true; 567 } 568 569 return false; 570 } 571 572 /// <summary> 573 /// Removes all Tags of the given type. Doesnt traverse the tree 574 /// </summary> 575 /// <param name="type">Type of the tags that should be removed</param> 576 /// <returns>true when tags were removed, false when no tags were found and removed</returns> RemoveTags(Type type)577 public bool RemoveTags(Type type) 578 { 579 bool ret = false; 580 581 ElementList list = SelectElements(type); 582 583 if (list.Count > 0) 584 ret = true; 585 586 foreach (Element e in list) 587 e.Remove(); 588 589 return ret; 590 } 591 592 /// <summary> 593 /// Removes all Tags of the given type. Doesnt traverse the tree 594 /// </summary> 595 /// <typeparam name="T">Type of the tags that should be removed</typeparam> 596 /// <returns>true when tags were removed, false when no tags were found and removed</returns> 597 public bool RemoveTags<T>() where T : Element 598 { 599 return RemoveTags(typeof (T)); 600 } 601 602 /// <summary> 603 /// Same as AddChild, but Replaces the childelement when it exists 604 /// </summary> 605 /// <param name="e"></param> ReplaceChild(Element e)606 public void ReplaceChild(Element e) 607 { 608 if (HasTag(e.TagName)) 609 RemoveTag(e.TagName); 610 611 AddChild(e); 612 } 613 Attribute(string name)614 public string Attribute(string name) 615 { 616 return (string) m_Attributes[name]; 617 } 618 619 /// <summary> 620 /// Removes a Attribute 621 /// </summary> 622 /// <param name="name">Attribute as string to remove</param> RemoveAttribute(string name)623 public void RemoveAttribute(string name) 624 { 625 if (HasAttribute(name)) 626 { 627 Attributes.Remove(name); 628 } 629 } 630 631 /// <summary> 632 /// Adds a new Attribue or changes a Attriv when already exists 633 /// </summary> 634 /// <param name="name">name of Attribute to add/change</param> 635 /// <param name="value">value of teh Attribute to add/change</param> SetAttribute(string name, string val)636 public void SetAttribute(string name, string val) 637 { 638 // When the attrib already exists then we overweite it 639 // So we must remove it first and add it again then 640 if (HasAttribute(name)) 641 { 642 Attributes.Remove(name); 643 } 644 m_Attributes.Add(name, val); 645 646 } 647 648 /// <summary> 649 /// 650 /// </summary> 651 /// <param name="name"></param> 652 /// <param name="value"></param> SetAttribute(string name, int value)653 public void SetAttribute(string name, int value) 654 { 655 SetAttribute(name, value.ToString()); 656 } 657 658 /// <summary> 659 /// 660 /// </summary> 661 /// <param name="name"></param> 662 /// <param name="value"></param> SetAttribute(string name, long value)663 public void SetAttribute(string name, long value) 664 { 665 SetAttribute(name, value.ToString()); 666 } 667 668 /// <summary> 669 /// Writes a boolean attribute, the value is either 'true' or 'false' 670 /// </summary> 671 /// <param name="name"></param> 672 /// <param name="val"></param> SetAttribute(string name, bool val)673 public void SetAttribute(string name, bool val) 674 { 675 // When the attrib already exists then we overweite it 676 // So we must remove it first and add it again then 677 if (HasAttribute(name)) 678 { 679 Attributes.Remove(name); 680 } 681 m_Attributes.Add(name, val ? "true" : "false"); 682 } 683 684 /// <summary> 685 /// Set a attribute of type Jid 686 /// </summary> 687 /// <param name="name"></param> 688 /// <param name="value"></param> SetAttribute(string name, Jid value)689 public void SetAttribute(string name, Jid value) 690 { 691 if (value != null) 692 SetAttribute(name, value.ToString()); 693 else 694 RemoveAttribute(name); 695 } 696 697 /// <summary> 698 /// Set a attribute from a double in english number format 699 /// </summary> 700 /// <param name="name"></param> 701 /// <param name="value"></param> SetAttribute(string name, double value)702 public void SetAttribute(string name, double value) 703 { 704 NumberFormatInfo nfi = new NumberFormatInfo(); 705 nfi.NumberGroupSeparator = "."; 706 SetAttribute(name, value, nfi); 707 } 708 709 /// <summary> 710 /// Set a attribute from a double with the given Format provider 711 /// </summary> 712 /// <param name="name"></param> 713 /// <param name="value"></param> 714 /// <param name="ifp"></param> SetAttribute(string name, double value, IFormatProvider ifp)715 public void SetAttribute(string name, double value, IFormatProvider ifp) 716 { 717 SetAttribute(name, value.ToString(ifp)); 718 } 719 720 SetNamespace(string value)721 public void SetNamespace(string value) 722 { 723 SetAttribute("xmlns", value); 724 } 725 GetFirstCDataNode()726 private CData GetFirstCDataNode() 727 { 728 foreach (Node ch in ChildNodes) 729 { 730 if (ch.NodeType == NodeType.Cdata) 731 return ch as CData; 732 } 733 return null; 734 } 735 736 /// <summary> 737 /// Has this Element some CDATA? 738 /// </summary> 739 /// <returns></returns> HasData()740 public bool HasData() 741 { 742 return GetFirstCDataNode() != null; 743 } 744 745 /// <summary> 746 /// Get the CDATA 747 /// </summary> 748 /// <returns></returns> GetData()749 public string GetData() 750 { 751 var data = GetFirstCDataNode(); 752 return data == null ? null : data.Value; 753 } 754 755 /// <summary> 756 /// Set the CDATA 757 /// </summary> 758 /// <param name="cdata"></param> SetData(string cdata)759 public void SetData(string cdata) 760 { 761 var data = GetFirstCDataNode(); 762 if (data == null) 763 { 764 data = new CData(); 765 AddChild(data); 766 } 767 data.Value = cdata; 768 } 769 770 public string InnerXml 771 { 772 get 773 { 774 if (ChildNodes.Count > 0) 775 { 776 string xml = ""; 777 try 778 { 779 for (int i = 0; i < ChildNodes.Count; i++) 780 { 781 if (ChildNodes.Item(i).NodeType == NodeType.Element) 782 xml += ChildNodes.Item(i).ToString(); 783 else if (ChildNodes.Item(i).NodeType == NodeType.Text) 784 xml += ChildNodes.Item(i).Value; 785 786 } 787 } 788 catch (Exception) 789 { 790 } 791 return xml; 792 793 } 794 return null; 795 } 796 set 797 { 798 Document doc = new Document(); 799 doc.LoadXml(value); 800 Element root = doc.RootElement; 801 if (root != null) 802 { 803 ChildNodes.Clear(); 804 AddChild(root); 805 } 806 807 } 808 } 809 810 /// <summary> 811 /// returns whether the current element has child elements or not. 812 /// cares only about element, not text nodes etc... 813 /// </summary> 814 public bool HasChildElements 815 { 816 get 817 { 818 foreach (Node e in ChildNodes) 819 { 820 if (e.NodeType == NodeType.Element) 821 return true; 822 } 823 return false; 824 } 825 } 826 827 /// <summary> 828 /// returns the first child element (no textNodes) 829 /// </summary> 830 public Element FirstChild 831 { 832 get 833 { 834 if (ChildNodes.Count > 0) 835 { 836 foreach (Node e in ChildNodes) 837 { 838 if (e.NodeType == NodeType.Element) 839 return e as Element; 840 } 841 return null; 842 } 843 return null; 844 } 845 } 846 847 /// <summary> 848 /// Returns the first ChildNode, doesnt matter of which type it is 849 /// </summary> 850 public Node FirstNode 851 { 852 get 853 { 854 if(ChildNodes.Count > 0) 855 return ChildNodes.Item(0) as Node; 856 return null; 857 } 858 } 859 860 /// <summary> 861 /// Returns the last ChildNode, doesnt matter of which type it is 862 /// </summary> 863 public Node LastNode 864 { 865 get 866 { 867 if(ChildNodes.Count > 0) 868 return ChildNodes.Item(ChildNodes.Count -1) as Node; 869 return null; 870 } 871 } 872 StartTag()873 internal string StartTag() 874 { 875 using (StringWriter sw = new StringWriter()) 876 { 877 using (XmlTextWriter tw = new XmlTextWriter(sw)) 878 { 879 tw.Formatting = Formatting.None; 880 881 if (Prefix == null) 882 tw.WriteStartElement(TagName); 883 else 884 tw.WriteStartElement(Prefix + ":" + TagName); 885 886 // Write Namespace 887 if (Namespace != null 888 && Namespace.Length != 0 889 ) 890 { 891 if (Prefix == null) 892 tw.WriteAttributeString("xmlns", Namespace); 893 else 894 tw.WriteAttributeString("xmlns:" + Prefix, Namespace); 895 } 896 897 foreach (string attName in this.Attributes.Keys) 898 { 899 tw.WriteAttributeString(attName, Attribute(attName)); 900 } 901 902 tw.Flush(); 903 tw.Close(); 904 905 return sw.ToString().Replace("/>", ">"); 906 } 907 } 908 } 909 EndTag()910 internal string EndTag() 911 { 912 if (Prefix == null) 913 return "</" + TagName + ">"; 914 return "</" + Prefix + ":" + TagName + ">"; 915 } 916 917 #region << Xml Select Functions >> 918 /// <summary> 919 /// Find a Element by type 920 /// </summary> 921 /// <param name="type"></param> 922 /// <returns></returns> SelectSingleElement(System.Type type)923 public Element SelectSingleElement(System.Type type) 924 { 925 return _SelectElement(this, type); 926 } 927 928 /// <summary> 929 /// find a Element by type and loop thru all children 930 /// </summary> 931 /// <param name="type"></param> 932 /// <param name="loopChildren"></param> 933 /// <returns></returns> SelectSingleElement(System.Type type, bool loopChildren)934 public Element SelectSingleElement(System.Type type, bool loopChildren) 935 { 936 return _SelectElement(this, type, true); 937 } 938 SelectSingleElement(string TagName)939 public Element SelectSingleElement(string TagName) 940 { 941 return _SelectElement(this, TagName); 942 } 943 SelectSingleElement(string TagName, bool traverseChildren)944 public Element SelectSingleElement(string TagName, bool traverseChildren) 945 { 946 return _SelectElement(this, TagName, true); 947 } 948 SelectSingleElement(string TagName, string AttribName, string AttribValue)949 public Element SelectSingleElement(string TagName, string AttribName, string AttribValue) 950 { 951 return _SelectElement(this, TagName, AttribName, AttribValue); 952 } 953 SelectSingleElement(string TagName, string ns)954 public Element SelectSingleElement(string TagName, string ns) 955 { 956 return _SelectElement(this, TagName, ns, true); 957 } 958 SelectSingleElement(string TagName, string ns, bool traverseChildren)959 public Element SelectSingleElement(string TagName, string ns, bool traverseChildren) 960 { 961 return _SelectElement(this, TagName, ns, traverseChildren); 962 } 963 964 public T SelectSingleElement<T>() where T : Element 965 { 966 return (T)_SelectElement(this, typeof(T)); 967 } 968 969 public T SelectSingleElement<T>(bool traverseChildren) where T : Element 970 { 971 return (T)_SelectElement(this, typeof(T), traverseChildren); 972 } 973 974 /// <summary> 975 /// Returns all childNodes with the given Tagname, 976 /// this function doesn't traverse the whole tree!!! 977 /// </summary> 978 /// <param name="TagName"></param> 979 /// <returns></returns> SelectElements(string TagName)980 public ElementList SelectElements(string TagName) 981 { 982 ElementList es = new ElementList(); 983 //return this._SelectElements(this, TagName, es); 984 return _SelectElements(this, TagName, es, false); 985 } 986 SelectElements(string TagName, bool traverseChildren)987 public ElementList SelectElements(string TagName, bool traverseChildren) 988 { 989 ElementList es = new ElementList(); 990 //return this._SelectElements(this, TagName, es); 991 return _SelectElements(this, TagName, es, traverseChildren); 992 } 993 SelectElements(System.Type type)994 public ElementList SelectElements(System.Type type) 995 { 996 ElementList es = new ElementList(); 997 return _SelectElements(this, type, es); 998 } 999 1000 /// <summary> 1001 /// returns a nodelist of all found nodes of the given Type 1002 /// </summary> 1003 /// <param name="e"></param> 1004 /// <param name="type"></param> 1005 /// <param name="es"></param> 1006 /// <returns></returns> _SelectElements(Element e, Type type, ElementList es)1007 private ElementList _SelectElements(Element e, Type type, ElementList es) 1008 { 1009 return _SelectElements(e, type, es, false); 1010 } 1011 _SelectElements(Element e, Type type, ElementList es, bool traverseChildren)1012 private ElementList _SelectElements(Element e, Type type, ElementList es, bool traverseChildren) 1013 { 1014 if (e.ChildNodes.Count > 0) 1015 { 1016 foreach(Node n in e.ChildNodes) 1017 { 1018 if (n.NodeType == NodeType.Element) 1019 { 1020 if (n.GetType() == type) 1021 { 1022 es.Add(n); 1023 } 1024 if (traverseChildren) 1025 _SelectElements((Element) n, type, es, true); 1026 } 1027 } 1028 } 1029 return es; 1030 } 1031 1032 /// <summary> 1033 /// Select a single element. 1034 /// This function doesnt traverse the whole tree and checks only the underlying childnodes 1035 /// </summary> 1036 /// <param name="se"></param> 1037 /// <param name="tagname"></param> 1038 /// <returns></returns> _SelectElement(Node se, string tagname)1039 private Element _SelectElement(Node se, string tagname) 1040 { 1041 return _SelectElement(se, tagname, false); 1042 } 1043 1044 /// <summary> 1045 /// Select a single element 1046 /// </summary> 1047 /// <param name="se"></param> 1048 /// <param name="tagname"></param> 1049 /// <param name="traverseChildren">when set to true then the function traverses the whole tree</param> 1050 /// <returns></returns> _SelectElement(Node se, string tagname, bool traverseChildren)1051 private Element _SelectElement(Node se, string tagname, bool traverseChildren) 1052 { 1053 Element rElement = null; 1054 1055 if (se.ChildNodes.Count > 0) 1056 { 1057 foreach(Node ch in se.ChildNodes) 1058 { 1059 if (ch.NodeType == NodeType.Element) 1060 { 1061 if ( ((Element) ch).TagName == tagname ) 1062 { 1063 rElement = (Element) ch; 1064 return rElement; 1065 } 1066 else 1067 { 1068 if( traverseChildren) 1069 { 1070 rElement = _SelectElement(ch, tagname, true); 1071 if (rElement != null) 1072 break; 1073 } 1074 } 1075 } 1076 } 1077 } 1078 1079 return rElement; 1080 } 1081 1082 _SelectElement(Node se, System.Type type)1083 private Element _SelectElement(Node se, System.Type type) 1084 { 1085 return _SelectElement(se, type, false); 1086 } 1087 _SelectElement(Node se, System.Type type, bool traverseChildren)1088 private Element _SelectElement(Node se, System.Type type, bool traverseChildren) 1089 { 1090 Element rElement = null; 1091 1092 if (se.ChildNodes.Count > 0) 1093 { 1094 foreach(Node ch in se.ChildNodes) 1095 { 1096 if (ch.NodeType == NodeType.Element) 1097 { 1098 if ( ch.GetType() == type ) 1099 { 1100 rElement = (Element) ch; 1101 return rElement; 1102 } 1103 else 1104 { 1105 if( traverseChildren) 1106 { 1107 rElement = _SelectElement(ch, type, true); 1108 if (rElement != null) 1109 break; 1110 } 1111 } 1112 } 1113 } 1114 } 1115 return rElement; 1116 } 1117 _SelectElement(Node se, string tagname, string AttribName, string AttribValue)1118 private Element _SelectElement(Node se, string tagname, string AttribName, string AttribValue) 1119 { 1120 Element rElement = null; 1121 1122 if (se.NodeType == NodeType.Element) 1123 { 1124 Element e = se as Element; 1125 if (e.m_TagName == tagname) 1126 { 1127 if (e.HasAttribute(AttribName)) 1128 { 1129 if (e.GetAttribute(AttribName) == AttribValue) 1130 { 1131 rElement = e; 1132 return rElement; 1133 } 1134 } 1135 } 1136 } 1137 1138 if (se.ChildNodes.Count > 0) 1139 { 1140 foreach(Node ch in se.ChildNodes) 1141 { 1142 rElement = _SelectElement(ch, tagname, AttribName, AttribValue); 1143 if (rElement != null) 1144 break; 1145 } 1146 } 1147 1148 return rElement; 1149 } 1150 1151 /// <summary> 1152 /// Find Element by Namespace 1153 /// </summary> 1154 /// <param name="se">The se.</param> 1155 /// <param name="tagname">The tagname.</param> 1156 /// <param name="nameSpace">The name space.</param> 1157 /// <param name="traverseChildren">if set to <c>true</c> [traverse children].</param> 1158 /// <returns></returns> _SelectElement(Node se, string tagname, string nameSpace, bool traverseChildren)1159 private Element _SelectElement(Node se, string tagname, string nameSpace, bool traverseChildren) 1160 { 1161 Element rElement = null; 1162 1163 if (se.ChildNodes.Count > 0) 1164 { 1165 foreach (Node ch in se.ChildNodes) 1166 { 1167 if (ch.NodeType == NodeType.Element) 1168 { 1169 Element e = ch as Element; 1170 if (e.TagName == tagname && e.Namespace == nameSpace) 1171 { 1172 rElement = (Element)ch; 1173 return rElement; 1174 } 1175 else 1176 { 1177 if (traverseChildren) 1178 { 1179 rElement = _SelectElement(ch, tagname, nameSpace, traverseChildren); 1180 if (rElement != null) 1181 break; 1182 } 1183 } 1184 } 1185 } 1186 } 1187 return rElement; 1188 } 1189 _SelectElements(Element e, string tagname, ElementList es, bool traverseChildren)1190 private ElementList _SelectElements(Element e, string tagname, ElementList es, bool traverseChildren) 1191 { 1192 if (e.ChildNodes.Count > 0) 1193 { 1194 foreach(Node n in e.ChildNodes) 1195 { 1196 if (n.NodeType == NodeType.Element) 1197 { 1198 if ( ((Element) n).m_TagName == tagname) 1199 { 1200 es.Add(n); 1201 } 1202 if (traverseChildren) 1203 _SelectElements((Element) n, tagname, es, true); 1204 } 1205 1206 } 1207 } 1208 return es; 1209 } 1210 1211 1212 public List<T> SelectElements<T>() where T : Element 1213 { 1214 return SelectElements<T>(false); 1215 } 1216 1217 public List<T> SelectElements<T>(bool traverseChildren) where T : Element 1218 { 1219 List<T> list = new List<T>(); 1220 return this._SelectElements<T>(this, list, traverseChildren); 1221 } 1222 1223 private List<T> _SelectElements<T>(Element e, List<T> list, bool traverseChildren) where T : Element 1224 { 1225 if (e.ChildNodes.Count > 0) 1226 { 1227 foreach (Node n in e.ChildNodes) 1228 { 1229 if (n.NodeType == NodeType.Element) 1230 { 1231 if (n.GetType() == typeof(T)) 1232 { 1233 list.Add(n as T); 1234 } 1235 if (traverseChildren) 1236 _SelectElements((Element)n, list, true); 1237 } 1238 } 1239 } 1240 return list; 1241 } 1242 #endregion 1243 } 1244 }