18 public class XmlElement
20 private readonly
bool hasPrefix;
21 private bool hasNameSpaces;
22 private bool hasDefaultNameSpace;
23 private bool hasAttributes;
24 private bool hasInnerValue;
25 private bool hasChildren;
26 private string innerValue;
27 private string defaultXmlNsUri;
36 public string Name {
get;
private set; }
40 public List<XmlElement>
Children {
get;
private set; }
44 public HashSet<XmlAttribute>
Attributes {
get;
private set; }
58 if (
string.IsNullOrEmpty(value))
61 hasInnerValue =
false;
76 internal XmlElement(
string name,
string prefix)
80 this.hasPrefix = !
string.IsNullOrEmpty(prefix);
90 internal void AddNameSpaceAttribute(
string prefix,
string rootNameSpace,
string uri)
92 if (
string.IsNullOrEmpty(prefix) ||
string.IsNullOrEmpty(uri))
104 hasNameSpaces =
true;
105 AddAttribute(prefix, uri, rootNameSpace);
112 internal void AddDefaultXmlNameSpace(
string defaultXmlNsUri)
114 this.defaultXmlNsUri = defaultXmlNsUri;
115 hasDefaultNameSpace =
true;
124 internal void AddAttribute(
string name,
string value,
string prefix =
"")
129 hasAttributes =
true;
131 Attributes.Add(XmlAttribute.CreateAttribute(name, value, prefix));
138 internal void AddAttribute(XmlAttribute? nullableAttribute)
140 if (!nullableAttribute.HasValue)
147 hasAttributes =
true;
156 internal void AddAttributes(IEnumerable<XmlAttribute> attributes)
158 if (attributes ==
null || !attributes.Any())
165 hasAttributes =
true;
167 foreach (XmlAttribute attribute
in attributes)
182 internal XmlElement AddChildElementWithAttribute(
string name,
string attributeName,
string attributeValue,
string namePrefix =
"",
string attributePrefix =
"")
184 XmlElement childElement = CreateElementWithAttribute(name, attributeName, attributeValue, namePrefix, attributePrefix);
185 AddChildElement(childElement);
196 internal XmlElement AddChildElementWithValue(
string name,
string innerValue,
string prefix =
"")
198 if (
string.IsNullOrEmpty(innerValue))
202 XmlElement childElement = CreateElement(name, prefix);
203 childElement.InnerValue = innerValue;
204 AddChildElement(childElement);
214 internal XmlElement AddChildElement(
string name,
string prefix =
"")
216 XmlElement childElement = CreateElement(name, prefix);
217 AddChildElement(childElement);
225 internal void AddChildElement(XmlElement xmlElement)
227 if (xmlElement ==
null)
243 internal void AddChildElements(IEnumerable<XmlElement> xmlElements)
245 if (xmlElements ==
null || !xmlElements.Any())
263 internal void AddChildElementBefore(XmlElement xmlElement, params
string[] ancestors)
265 if (xmlElement ==
null)
269 if (hasChildren && ancestors !=
null)
271 for (
int ancestorIndex = 0; ancestorIndex < ancestors.Length; ancestorIndex++)
273 for (
int childIndex = 0; childIndex <
Children.Count; childIndex++)
275 if (
Children[childIndex].
Name == ancestors[ancestorIndex])
277 Children.Insert(childIndex, xmlElement);
283 throw new NanoXLSX.Exceptions.IOException(
"None of the specified ancestor elements were found");
292 internal void AddChildElementAfter(XmlElement xmlElement, params
string[] successors)
294 if (xmlElement ==
null)
298 if (hasChildren && successors !=
null)
300 for (
int successorIndex = 0; successorIndex < successors.Length; successorIndex++)
302 for (
int childIndex =
Children.Count - 1; childIndex >= 0; childIndex--)
304 if (
Children[childIndex].
Name == successors[successorIndex])
306 Children.Insert(childIndex + 1, xmlElement);
312 throw new NanoXLSX.Exceptions.IOException(
"None of the specified successor elements were found");
321 XmlDocument doc =
new XmlDocument
325 XmlNamespaceManager nsManager =
new XmlNamespaceManager(doc.NameTable);
330 if (nameSpace.Key ==
"xmlns")
334 nsManager.AddNamespace(nameSpace.Key, nameSpace.Value);
338 System.Xml.XmlElement rootElement =
null;
339 if (hasDefaultNameSpace)
341 rootElement = XmlElement.CreateXmlElement(doc,
this, nsManager, defaultXmlNsUri);
345 rootElement = XmlElement.CreateXmlElement(doc,
this, nsManager);
347 doc.AppendChild(rootElement);
356 internal void WriteTo(XmlWriter writer,
string defaultNs =
null)
358 string elementDefaultNs = hasDefaultNameSpace ? defaultXmlNsUri : defaultNs;
367 writer.WriteStartElement(
Prefix,
Name, nsUri);
371 writer.WriteStartElement(
Name, elementDefaultNs);
378 if (ns.Key ==
"xmlns")
382 writer.WriteAttributeString(
"xmlns", ns.Key,
null, ns.Value);
392 if (attr.Prefix ==
"xmlns")
396 string attrNsUri =
null;
401 writer.WriteAttributeString(attr.Prefix, attr.Name, attrNsUri, attr.Value);
405 int colonIndex = attr.Name.IndexOf(
':');
410 string implicitPrefix = attr.Name.Substring(0, colonIndex);
411 string localName = attr.Name.Substring(colonIndex + 1);
417 writer.WriteAttributeString(implicitPrefix, localName, nsUri, attr.Value);
421 writer.WriteAttributeString(attr.Name, attr.Value);
429 writer.WriteString(innerValue);
434 foreach (XmlElement child
in Children)
436 child.WriteTo(writer, elementDefaultNs);
440 writer.WriteEndElement();
452 return Enumerable.Empty<XmlElement>();
454 List<XmlElement> result =
new List<XmlElement>();
455 foreach (XmlElement child
in Children)
457 if (child.
Name == name)
503 List<XmlElement> result =
new List<XmlElement>();
504 foreach (XmlElement child
in Children)
506 if (child.Name == elementName && child.hasAttributes)
508 XmlAttribute? attribute = XmlAttribute.FindAttribute(attributeName, child.Attributes);
509 if (attribute !=
null)
511 if (!useValue || (useValue && attribute.Value.Value == attributeValue))
517 result.AddRange(child.FindChildElementsByNameAndAttribute(elementName, attributeName, attributeValue, useValue));
528 internal static XmlElement CreateElement(
string name,
string prefix =
"")
530 return new XmlElement(name, prefix);
542 internal static XmlElement CreateElementWithAttribute(
string name,
string attributeName,
string attributeValue,
string namePrefix =
"",
string attributePrefix =
"")
544 XmlElement element =
new XmlElement(name, namePrefix)
548 element.Attributes.Add(XmlAttribute.CreateAttribute(attributeName, attributeValue, attributePrefix));
549 element.hasAttributes =
true;
561 private static System.Xml.XmlElement CreateXmlElement(XmlDocument doc, XmlElement customElement, XmlNamespaceManager nsManager,
string defaultXmlNsUri =
null)
563 System.Xml.XmlElement xmlElem;
564 if (customElement.hasPrefix)
566 xmlElem = doc.CreateElement(customElement.Prefix, customElement.Name, nsManager.LookupNamespace(customElement.Prefix));
570 xmlElem = doc.CreateElement(customElement.Name, defaultXmlNsUri);
574 if (customElement.hasAttributes)
576 foreach (var attr
in customElement.Attributes)
580 System.Xml.XmlAttribute xmlAttr = doc.CreateAttribute(attr.Prefix, attr.Name, nsManager.LookupNamespace(attr.Prefix));
581 xmlAttr.Value = attr.Value;
582 xmlElem.Attributes.Append(xmlAttr);
586 xmlElem.SetAttribute(attr.Name, attr.Value);
592 if (customElement.hasInnerValue)
594 xmlElem.InnerText = customElement.InnerValue;
598 if (customElement.hasChildren)
600 foreach (var child
in customElement.Children)
602 System.Xml.XmlElement childXmlElem = XmlElement.CreateXmlElement(doc, child, nsManager, defaultXmlNsUri);
603 xmlElem.AppendChild(childXmlElem);