Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Async/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/XmlHelper.cs @ 13329

Last change on this file since 13329 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 22.6 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change                     Date
28 * ******************************************************************************
29 * Jan Källman        Initial Release            2009-10-01
30 * Jan Källman        License changed GPL-->LGPL 2011-12-27
31 * Eyal Seagull       Add "CreateComplexNode"    2012-04-03
32 * Eyal Seagull       Add "DeleteTopNode"        2012-04-13
33 *******************************************************************************/
34
35using System;
36using System.Collections.Generic;
37using System.Text;
38using System.Xml;
39using OfficeOpenXml.Style;
40using System.Globalization;
41using System.IO;
42namespace OfficeOpenXml
43{
44  /// <summary>
45  /// Help class containing XML functions.
46  /// Can be Inherited
47  /// </summary>
48  public abstract class XmlHelper
49  {
50    internal delegate int ChangedEventHandler(StyleBase sender, Style.StyleChangeEventArgs e);
51
52    internal XmlHelper(XmlNamespaceManager nameSpaceManager)
53    {
54      TopNode = null;
55      NameSpaceManager = nameSpaceManager;
56    }
57
58    internal XmlHelper(XmlNamespaceManager nameSpaceManager, XmlNode topNode)
59    {
60      TopNode = topNode;
61      NameSpaceManager = nameSpaceManager;
62    }
63    //internal bool ChangedFlag;
64    internal XmlNamespaceManager NameSpaceManager { get; set; }
65    internal XmlNode TopNode { get; set; }
66    string[] _schemaNodeOrder = null;
67    /// <summary>
68    /// Schema order list
69    /// </summary>
70    internal string[] SchemaNodeOrder
71    {
72      get
73      {
74        return _schemaNodeOrder;
75      }
76      set
77      {
78        _schemaNodeOrder = value;
79      }
80    }
81    internal XmlNode CreateNode(string path)
82    {
83      if (path == "")
84        return TopNode;
85      else
86        return CreateNode(path, false);
87    }
88    internal XmlNode CreateNode(string path, bool insertFirst)
89    {
90      XmlNode node = TopNode;
91      XmlNode prependNode = null;
92      foreach (string subPath in path.Split('/'))
93      {
94        XmlNode subNode = node.SelectSingleNode(subPath, NameSpaceManager);
95        if (subNode == null)
96        {
97          string nodeName;
98          string nodePrefix;
99
100          string nameSpaceURI = "";
101          string[] nameSplit = subPath.Split(':');
102
103          if (SchemaNodeOrder != null && subPath[0] != '@')
104          {
105            insertFirst = false;
106            prependNode = GetPrependNode(subPath, node);
107          }
108
109          if (nameSplit.Length > 1)
110          {
111            nodePrefix = nameSplit[0];
112            if (nodePrefix[0] == '@') nodePrefix = nodePrefix.Substring(1, nodePrefix.Length - 1);
113            nameSpaceURI = NameSpaceManager.LookupNamespace(nodePrefix);
114            nodeName = nameSplit[1];
115          }
116          else
117          {
118            nodePrefix = "";
119            nameSpaceURI = "";
120            nodeName = nameSplit[0];
121          }
122          if (subPath.StartsWith("@"))
123          {
124            XmlAttribute addedAtt = node.OwnerDocument.CreateAttribute(subPath.Substring(1, subPath.Length - 1), nameSpaceURI);  //nameSpaceURI
125            node.Attributes.Append(addedAtt);
126          }
127          else
128          {
129            if (nodePrefix == "")
130            {
131              subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceURI);
132            }
133            else
134            {
135              if (nodePrefix == "" || (node.OwnerDocument != null && node.OwnerDocument.DocumentElement != null && node.OwnerDocument.DocumentElement.NamespaceURI == nameSpaceURI &&
136                  node.OwnerDocument.DocumentElement.Prefix == ""))
137              {
138                subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceURI);
139              }
140              else
141              {
142                subNode = node.OwnerDocument.CreateElement(nodePrefix, nodeName, nameSpaceURI);
143              }
144            }
145            if (prependNode != null)
146            {
147              node.InsertBefore(subNode, prependNode);
148              prependNode = null;
149            }
150            else if (insertFirst)
151            {
152              node.PrependChild(subNode);
153            }
154            else
155            {
156              node.AppendChild(subNode);
157            }
158          }
159        }
160        node = subNode;
161      }
162      return node;
163    }
164
165    /// <summary>
166    /// Options to insert a node in the XmlDocument
167    /// </summary>
168    internal enum eNodeInsertOrder
169    {
170      /// <summary>
171      /// Insert as first node of "topNode"
172      /// </summary>
173      First,
174
175      /// <summary>
176      /// Insert as the last child of "topNode"
177      /// </summary>
178      Last,
179
180      /// <summary>
181      /// Insert after the "referenceNode"
182      /// </summary>
183      After,
184
185      /// <summary>
186      /// Insert before the "referenceNode"
187      /// </summary>
188      Before,
189
190      /// <summary>
191      /// Use the Schema List to insert in the right order. If the Schema list
192      /// is null or empty, consider "Last" as the selected option
193      /// </summary>
194      SchemaOrder
195    }
196
197    /// <summary>
198    /// Create a complex node. Insert the node according to SchemaOrder
199    /// using the TopNode as the parent
200    /// </summary>
201    /// <param name="path"></param>
202    /// <returns></returns>
203    internal XmlNode CreateComplexNode(
204      string path)
205    {
206      return CreateComplexNode(
207        TopNode,
208        path,
209        eNodeInsertOrder.SchemaOrder,
210        null);
211    }
212
213    /// <summary>
214    /// Create a complex node. Insert the node according to the <paramref name="path"/>
215    /// using the <paramref name="topNode"/> as the parent
216    /// </summary>
217    /// <param name="topNode"></param>
218    /// <param name="path"></param>
219    /// <returns></returns>
220    internal XmlNode CreateComplexNode(
221      XmlNode topNode,
222      string path)
223    {
224      return CreateComplexNode(
225        topNode,
226        path,
227        eNodeInsertOrder.SchemaOrder,
228        null);
229    }
230
231    /// <summary>
232    /// Creates complex XML nodes
233    /// </summary>
234    /// <remarks>
235    /// 1. "d:conditionalFormatting"
236    ///   1.1. Creates/find the first "conditionalFormatting" node
237    ///
238    /// 2. "d:conditionalFormatting/@sqref"
239    ///   2.1. Creates/find the first "conditionalFormatting" node
240    ///   2.2. Creates (if not exists) the @sqref attribute
241    ///
242    /// 3. "d:conditionalFormatting/@id='7'/@sqref='A9:B99'"
243    ///   3.1. Creates/find the first "conditionalFormatting" node
244    ///   3.2. Creates/update its @id attribute to "7"
245    ///   3.3. Creates/update its @sqref attribute to "A9:B99"
246    ///
247    /// 4. "d:conditionalFormatting[@id='7']/@sqref='X1:X5'"
248    ///   4.1. Creates/find the first "conditionalFormatting" node with @id=7
249    ///   4.2. Creates/update its @sqref attribute to "X1:X5"
250    ///
251    /// 5. "d:conditionalFormatting[@id='7']/@id='8'/@sqref='X1:X5'/d:cfRule/@id='AB'"
252    ///   5.1. Creates/find the first "conditionalFormatting" node with @id=7
253    ///   5.2. Set its @id attribute to "8"
254    ///   5.2. Creates/update its @sqref attribute and set it to "X1:X5"
255    ///   5.3. Creates/find the first "cfRule" node (inside the node)
256    ///   5.4. Creates/update its @id attribute to "AB"
257    ///
258    /// 6. "d:cfRule/@id=''"
259    ///   6.1. Creates/find the first "cfRule" node
260    ///   6.1. Remove the @id attribute
261    /// </remarks>
262    /// <param name="topNode"></param>
263    /// <param name="path"></param>
264    /// <param name="nodeInsertOrder"></param>
265    /// <param name="referenceNode"></param>
266    /// <returns>The last node creates/found</returns>
267    internal XmlNode CreateComplexNode(
268      XmlNode topNode,
269      string path,
270      eNodeInsertOrder nodeInsertOrder,
271      XmlNode referenceNode)
272    {
273      // Path is obrigatory
274      if ((path == null) || (path == string.Empty))
275      {
276        return topNode;
277      }
278
279      XmlNode node = topNode;
280      string nameSpaceURI = string.Empty;
281
282      //TODO: BUG: when the "path" contains "/" in an attrribue value, it gives an error.
283
284      // Separate the XPath to Nodes and Attributes
285      foreach (string subPath in path.Split('/'))
286      {
287        // The subPath can be any one of those:
288        // nodeName
289        // x:nodeName
290        // nodeName[find criteria]
291        // x:nodeName[find criteria]
292        // @attribute
293        // @attribute='attribute value'
294
295        // Check if the subPath has at least one character
296        if (subPath.Length > 0)
297        {
298          // Check if the subPath is an attribute (with or without value)
299          if (subPath.StartsWith("@"))
300          {
301            // @attribute                   --> Create attribute
302            // @attribute=''                --> Remove attribute
303            // @attribute='attribute value' --> Create attribute + update value
304            string[] attributeSplit = subPath.Split('=');
305            string attributeName = attributeSplit[0].Substring(1, attributeSplit[0].Length - 1);
306            string attributeValue = null; // Null means no attribute value
307
308            // Check if we have an attribute value to set
309            if (attributeSplit.Length > 1)
310            {
311              // Remove the ' or " from the attribute value
312              attributeValue = attributeSplit[1].Replace("'", "").Replace("\"", "");
313            }
314
315            // Get the attribute (if exists)
316            XmlAttribute attribute = (XmlAttribute)(node.Attributes.GetNamedItem(attributeName));
317
318            // Remove the attribute if value is empty (not null)
319            if (attributeValue == string.Empty)
320            {
321              // Only if the attribute exists
322              if (attribute != null)
323              {
324                node.Attributes.Remove(attribute);
325              }
326            }
327            else
328            {
329              // Create the attribue if does not exists
330              if (attribute == null)
331              {
332                // Create the attribute
333                attribute = node.OwnerDocument.CreateAttribute(
334                  attributeName);
335
336                // Add it to the current node
337                node.Attributes.Append(attribute);
338              }
339
340              // Update the attribute value
341              if (attributeValue != null)
342              {
343                node.Attributes[attributeName].Value = attributeValue;
344              }
345            }
346          }
347          else
348          {
349            // nodeName
350            // x:nodeName
351            // nodeName[find criteria]
352            // x:nodeName[find criteria]
353
354            // Look for the node (with or without filter criteria)
355            XmlNode subNode = node.SelectSingleNode(subPath, NameSpaceManager);
356
357            // Check if the node does not exists
358            if (subNode == null)
359            {
360              string nodeName;
361              string nodePrefix;
362              string[] nameSplit = subPath.Split(':');
363              nameSpaceURI = string.Empty;
364
365              // Check if the name has a prefix like "d:nodeName"
366              if (nameSplit.Length > 1)
367              {
368                nodePrefix = nameSplit[0];
369                nameSpaceURI = NameSpaceManager.LookupNamespace(nodePrefix);
370                nodeName = nameSplit[1];
371              }
372              else
373              {
374                nodePrefix = string.Empty;
375                nameSpaceURI = string.Empty;
376                nodeName = nameSplit[0];
377              }
378
379              // Check if we have a criteria part in the node name
380              if (nodeName.IndexOf("[") > 0)
381              {
382                // remove the criteria from the node name
383                nodeName = nodeName.Substring(0, nodeName.IndexOf("["));
384              }
385
386              if (nodePrefix == string.Empty)
387              {
388                subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceURI);
389              }
390              else
391              {
392                if (node.OwnerDocument != null
393                  && node.OwnerDocument.DocumentElement != null
394                  && node.OwnerDocument.DocumentElement.NamespaceURI == nameSpaceURI
395                  && node.OwnerDocument.DocumentElement.Prefix == string.Empty)
396                {
397                  subNode = node.OwnerDocument.CreateElement(
398                    nodeName,
399                    nameSpaceURI);
400                }
401                else
402                {
403                  subNode = node.OwnerDocument.CreateElement(
404                    nodePrefix,
405                    nodeName,
406                    nameSpaceURI);
407                }
408              }
409
410              // Check if we need to use the "SchemaOrder"
411              if (nodeInsertOrder == eNodeInsertOrder.SchemaOrder)
412              {
413                // Check if the Schema Order List is empty
414                if ((SchemaNodeOrder == null) || (SchemaNodeOrder.Length == 0))
415                {
416                  // Use the "Insert Last" option when Schema Order List is empty
417                  nodeInsertOrder = eNodeInsertOrder.Last;
418                }
419                else
420                {
421                  // Find the prepend node in order to insert
422                  referenceNode = GetPrependNode(nodeName, node);
423
424                  if (referenceNode != null)
425                  {
426                    nodeInsertOrder = eNodeInsertOrder.Before;
427                  }
428                  else
429                  {
430                    nodeInsertOrder = eNodeInsertOrder.Last;
431                  }
432                }
433              }
434
435              switch (nodeInsertOrder)
436              {
437                case eNodeInsertOrder.After:
438                  node.InsertAfter(subNode, referenceNode);
439                                    referenceNode = null;
440                                    break;
441
442                case eNodeInsertOrder.Before:
443                  node.InsertBefore(subNode, referenceNode);
444                                    referenceNode = null;
445                  break;
446
447                case eNodeInsertOrder.First:
448                  node.PrependChild(subNode);
449                  break;
450
451                case eNodeInsertOrder.Last:
452                  node.AppendChild(subNode);
453                  break;
454              }
455            }
456
457            // Make the newly created node the top node when the rest of the path
458            // is being evaluated. So newly created nodes will be the children of the
459            // one we just created.
460            node = subNode;
461          }
462        }
463      }
464
465      // Return the last created/found node
466      return node;
467    }
468
469    /// <summary>
470    /// return Prepend node
471    /// </summary>
472    /// <param name="nodeName">name of the node to check</param>
473    /// <param name="node">Topnode to check children</param>
474    /// <returns></returns>
475    private XmlNode GetPrependNode(string nodeName, XmlNode node)
476    {
477      int pos = GetNodePos(nodeName);
478      if (pos < 0)
479      {
480        return null;
481      }
482      XmlNode prependNode = null;
483      foreach (XmlNode childNode in node.ChildNodes)
484      {
485        int childPos = GetNodePos(childNode.Name);
486        if (childPos > -1)  //Found?
487        {
488          if (childPos > pos) //Position is before
489          {
490            prependNode = childNode;
491            break;
492          }
493        }
494      }
495      return prependNode;
496    }
497    private int GetNodePos(string nodeName)
498    {
499      int ix = nodeName.IndexOf(":");
500      if (ix > 0)
501      {
502        nodeName = nodeName.Substring(ix + 1, nodeName.Length - (ix + 1));
503      }
504      for (int i = 0; i < _schemaNodeOrder.Length; i++)
505      {
506        if (nodeName == _schemaNodeOrder[i])
507        {
508          return i;
509        }
510      }
511      return -1;
512    }
513    internal void DeleteAllNode(string path)
514    {
515      string[] split = path.Split('/');
516      XmlNode node = TopNode;
517      foreach (string s in split)
518      {
519        node = node.SelectSingleNode(s, NameSpaceManager);
520        if (node != null)
521        {
522          if (node is XmlAttribute)
523          {
524            (node as XmlAttribute).OwnerElement.Attributes.Remove(node as XmlAttribute);
525          }
526          else
527          {
528            node.ParentNode.RemoveChild(node);
529          }
530        }
531        else
532        {
533          break;
534        }
535      }
536    }
537    internal void DeleteNode(string path)
538    {
539      var node = TopNode.SelectSingleNode(path, NameSpaceManager);
540      if (node != null)
541      {
542        if (node is XmlAttribute)
543        {
544          var att = (XmlAttribute)node;
545          att.OwnerElement.Attributes.Remove(att);
546        }
547        else
548        {
549          node.ParentNode.RemoveChild(node);
550        }
551      }
552    }
553    internal void DeleteTopNode()
554    {
555      TopNode.ParentNode.RemoveChild(TopNode);
556    }
557    internal void SetXmlNodeString(string path, string value)
558    {
559      SetXmlNodeString(TopNode, path, value, false, false);
560    }
561    internal void SetXmlNodeString(string path, string value, bool removeIfBlank)
562    {
563      SetXmlNodeString(TopNode, path, value, removeIfBlank, false);
564    }
565    internal void SetXmlNodeString(XmlNode node, string path, string value)
566    {
567      SetXmlNodeString(node, path, value, false, false);
568    }
569    internal void SetXmlNodeString(XmlNode node, string path, string value, bool removeIfBlank)
570    {
571      SetXmlNodeString(node, path, value, removeIfBlank, false);
572    }
573    internal void SetXmlNodeString(XmlNode node, string path, string value, bool removeIfBlank, bool insertFirst)
574    {
575      if (node == null)
576      {
577        return;
578      }
579      if (value == "" && removeIfBlank)
580      {
581        DeleteAllNode(path);
582      }
583      else
584      {
585        XmlNode nameNode = node.SelectSingleNode(path, NameSpaceManager);
586        if (nameNode == null)
587        {
588          CreateNode(path, insertFirst);
589          nameNode = node.SelectSingleNode(path, NameSpaceManager);
590        }
591        //if (nameNode.InnerText != value) HasChanged();
592        nameNode.InnerText = value;
593      }
594    }
595    internal void SetXmlNodeBool(string path, bool value)
596    {
597      SetXmlNodeString(TopNode, path, value ? "1" : "0", false, false);
598    }
599    internal void SetXmlNodeBool(string path, bool value, bool removeIf)
600    {
601      if (value == removeIf)
602      {
603        var node = TopNode.SelectSingleNode(path, NameSpaceManager);
604        if (node != null)
605        {
606          if (node is XmlAttribute)
607          {
608            var elem = (node as XmlAttribute).OwnerElement;
609            elem.ParentNode.RemoveChild(elem);
610          }
611          else
612          {
613            TopNode.RemoveChild(node);
614          }
615        }
616      }
617      else
618      {
619        SetXmlNodeString(TopNode, path, value ? "1" : "0", false, false);
620      }
621    }
622    internal bool ExistNode(string path)
623    {
624      if (TopNode == null || TopNode.SelectSingleNode(path, NameSpaceManager) == null)
625      {
626        return false;
627      }
628      else
629      {
630        return true;
631      }
632    }
633    internal bool? GetXmlNodeBoolNullable(string path)
634    {
635      var value = GetXmlNodeString(path);
636      if (string.IsNullOrEmpty(value))
637      {
638        return null;
639      }
640      return GetXmlNodeBool(path);
641    }
642    internal bool GetXmlNodeBool(string path)
643    {
644      return GetXmlNodeBool(path, false);
645    }
646    internal bool GetXmlNodeBool(string path, bool blankValue)
647    {
648      string value = GetXmlNodeString(path);
649      if (value == "1" || value == "-1" || value.Equals("true",StringComparison.InvariantCultureIgnoreCase))
650      {
651        return true;
652      }
653      else if (value == "")
654      {
655        return blankValue;
656      }
657      else
658      {
659        return false;
660      }
661    }
662    internal int GetXmlNodeInt(string path)
663    {
664      int i;
665      if (int.TryParse(GetXmlNodeString(path), out i))
666      {
667        return i;
668      }
669      else
670      {
671        return int.MinValue;
672      }
673    }
674        internal int? GetXmlNodeIntNull(string path)
675        {
676            int i;
677            string s = GetXmlNodeString(path);
678            if (s!="" && int.TryParse(s, out i))
679            {
680                return i;
681            }
682            else
683            {
684                return null;
685            }
686        }
687
688    internal decimal GetXmlNodeDecimal(string path)
689    {
690      decimal d;
691      if (decimal.TryParse(GetXmlNodeString(path), NumberStyles.Any, CultureInfo.InvariantCulture, out d))
692      {
693        return d;
694      }
695      else
696      {
697        return 0;
698      }
699    }
700        internal decimal? GetXmlNodeDecimalNull(string path)
701        {
702            decimal d;
703            if (decimal.TryParse(GetXmlNodeString(path), NumberStyles.Any, CultureInfo.InvariantCulture, out d))
704            {
705                return d;
706            }
707            else
708            {
709                return null;
710            }
711        }
712        internal double? GetXmlNodeDoubleNull(string path)
713    {
714      string s = GetXmlNodeString(path);
715      if (s == "")
716      {
717        return null;
718      }
719      else
720      {
721        double v;
722        if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out v))
723        {
724          return v;
725        }
726        else
727        {
728          return null;
729        }
730      }
731    }
732    internal double GetXmlNodeDouble(string path)
733    {
734      string s = GetXmlNodeString(path);
735      if (s == "")
736      {
737        return double.NaN;
738      }
739      else
740      {
741        double v;
742        if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out v))
743        {
744          return v;
745        }
746        else
747        {
748          return double.NaN;
749        }
750      }
751    }
752    internal string GetXmlNodeString(XmlNode node, string path)
753    {
754      if (node == null)
755      {
756        return "";
757      }
758
759      XmlNode nameNode = node.SelectSingleNode(path, NameSpaceManager);
760
761      if (nameNode != null)
762      {
763        if (nameNode.NodeType == XmlNodeType.Attribute)
764        {
765          return nameNode.Value != null ? nameNode.Value : "";
766        }
767        else
768        {
769          return nameNode.InnerText;
770        }
771      }
772      else
773      {
774        return "";
775      }
776    }
777    internal string GetXmlNodeString(string path)
778    {
779            return GetXmlNodeString(TopNode, path);
780    }
781    internal static Uri GetNewUri(Packaging.ZipPackage package, string sUri)
782    {
783      return GetNewUri(package, sUri, 1);
784    }
785        internal static Uri GetNewUri(Packaging.ZipPackage package, string sUri, int id)
786    {
787      Uri uri;
788      do
789      {
790        uri = new Uri(string.Format(sUri, id++), UriKind.Relative);
791      }
792      while (package.PartExists(uri));
793      return uri;
794    }
795    /// <summary>
796    /// Insert the new node before any of the nodes in the comma separeted list
797    /// </summary>
798    /// <param name="parentNode">Parent node</param>
799    /// <param name="beforeNodes">comma separated list containing nodes to insert after. Left to right order</param>
800    /// <param name="newNode">The new node to be inserterd</param>
801    internal void InserAfter(XmlNode parentNode, string beforeNodes, XmlNode newNode)
802    {
803      string[] nodePaths = beforeNodes.Split(',');
804
805      foreach (string nodePath in nodePaths)
806      {
807        XmlNode node = parentNode.SelectSingleNode(nodePath, NameSpaceManager);
808        if (node != null)
809        {
810          parentNode.InsertAfter(newNode, node);
811          return;
812        }
813      }
814      parentNode.InsertAfter(newNode, null);
815    }
816        internal static void LoadXmlSafe(XmlDocument xmlDoc, Stream stream)
817        {
818            XmlReaderSettings settings = new XmlReaderSettings();
819            //Disable entity parsing (to aviod xmlbombs, External Entity Attacks etc).
820            settings.ProhibitDtd = true;
821            XmlReader reader = XmlReader.Create(stream, settings);
822            xmlDoc.Load(reader);
823        }
824        internal static void LoadXmlSafe(XmlDocument xmlDoc, string xml, Encoding encoding)
825        {
826            var stream = new MemoryStream(encoding.GetBytes(xml));
827            LoadXmlSafe(xmlDoc, stream);
828        }
829  }
830}
Note: See TracBrowser for help on using the repository browser.