Example #1
0
        public static void ImportWhiteSpace()
        {
            var whitespace = "        ";
            var tempDoc = new XmlDocument();
            var nodeToImport = tempDoc.CreateWhitespace(whitespace);

            var xmlDocument = new XmlDocument();
            var node = xmlDocument.ImportNode(nodeToImport, true);

            Assert.Equal(xmlDocument, node.OwnerDocument);
            Assert.Equal(XmlNodeType.Whitespace, node.NodeType);
            Assert.Equal(whitespace, node.Value);
        }
Example #2
0
        public static XmlNode CreateNode(XmlDocument doc, XmlNodeType nodeType)
        {
            Assert.NotNull(doc);

            switch (nodeType)
            {
                case XmlNodeType.CDATA:
                    return doc.CreateCDataSection(@"&lt; &amp; <tag> < ! > & </tag> 	 ");
                case XmlNodeType.Comment:
                    return doc.CreateComment(@"comment");
                case XmlNodeType.Element:
                    return doc.CreateElement("E");
                case XmlNodeType.Text:
                    return doc.CreateTextNode("text");
                case XmlNodeType.Whitespace:
                    return doc.CreateWhitespace(@"	  ");
                case XmlNodeType.SignificantWhitespace:
                    return doc.CreateSignificantWhitespace("	");
                default:
                    throw new ArgumentException("Wrong XmlNodeType: '" + nodeType + "'");
            }
        }
Example #3
0
 public override void WriteWhitespace(string ws)
 {
     WritePossiblyTopLevelNode(doc.CreateWhitespace(ws), true);
 }
Example #4
0
        public Boolean SaveCustomMapping(String customMapPath, System.Windows.Forms.Control[] buttons)
        {
            Boolean Saved = true;

            try
            {
                XmlNode Node;
                m_Xdoc.RemoveAll();
                Node = m_Xdoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty);
                m_Xdoc.AppendChild(Node);
                Node = m_Xdoc.CreateComment(String.Format(" Custom Control Mapping Data. {0} ", DateTime.Now));
                m_Xdoc.AppendChild(Node);
                Node = m_Xdoc.CreateWhitespace("\r\n");
                m_Xdoc.AppendChild(Node);
                Node = m_Xdoc.CreateNode(XmlNodeType.Element, "Control", null);

                XmlNode Key     = m_Xdoc.CreateNode(XmlNodeType.Element, "Key", null);
                XmlNode KeyType = m_Xdoc.CreateNode(XmlNodeType.Element, "KeyType", null);
                XmlNode Button  = m_Xdoc.CreateNode(XmlNodeType.Element, "Button", null);

                foreach (var button in buttons)
                {
                    try
                    {
                        // Save even if string (for xbox controller buttons)
                        if (button.Tag != null)
                        {
                            XmlNode buttonNode;
                            string  keyType = String.Empty;
                            if (button.ForeColor == System.Drawing.Color.Red)
                            {
                                keyType += DS4KeyType.Repeat;
                            }
                            if (button.Font.Bold)
                            {
                                keyType += DS4KeyType.ScanCode;
                            }
                            if (keyType != String.Empty)
                            {
                                buttonNode           = m_Xdoc.CreateNode(XmlNodeType.Element, button.Name, null);
                                buttonNode.InnerText = keyType;
                                KeyType.AppendChild(buttonNode);
                            }
                            buttonNode           = m_Xdoc.CreateNode(XmlNodeType.Element, button.Name, null);
                            buttonNode.InnerText = button.Tag.ToString();
                            if (button.Tag is Int32 || button.Tag is UInt16)
                            {
                                Key.AppendChild(buttonNode);
                            }
                            else
                            {
                                Button.AppendChild(buttonNode);
                            }
                        }
                    }
                    catch
                    {
                        Saved = false;
                    }
                }
                m_Xdoc.AppendChild(Node);
                if (Button.HasChildNodes)
                {
                    Node.AppendChild(Button);
                }
                if (Key.HasChildNodes)
                {
                    Node.AppendChild(Key);
                }
                if (KeyType.HasChildNodes)
                {
                    Node.AppendChild(KeyType);
                }
                m_Xdoc.Save(customMapPath);
            }
            catch (Exception)
            {
                Saved = false;
            }
            return(Saved);
        }
Example #5
0
 public XmlWhitespace CreateWhitespace(string text)
 {
     return(_doc.CreateWhitespace(text));
 }
 private static void PrependComment(XmlDocument root, XmlNode parent, String comment)
 {
     parent.PrependChild(root.CreateWhitespace("\r\n"));
     parent.PrependChild(root.CreateComment(comment));
     parent.PrependChild(root.CreateWhitespace("\r\n"));
 }
Example #7
0
        private void DeserializeValue(JsonReader reader, XmlDocument document, XmlNamespaceManager manager, string propertyName, XmlNode currentNode)
        {
            switch (propertyName)
            {
            case TextName:
                currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString()));
                break;

            case CDataName:
                currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString()));
                break;

            case WhitespaceName:
                currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString()));
                break;

            case SignificantWhitespaceName:
                currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString()));
                break;

            default:
                // processing instructions and the xml declaration start with ?
                if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?')
                {
                    if (propertyName == DeclarationName)
                    {
                        string version    = null;
                        string encoding   = null;
                        string standalone = null;
                        while (reader.Read() && reader.TokenType != JsonToken.EndObject)
                        {
                            switch (reader.Value.ToString())
                            {
                            case "@version":
                                reader.Read();
                                version = reader.Value.ToString();
                                break;

                            case "@encoding":
                                reader.Read();
                                encoding = reader.Value.ToString();
                                break;

                            case "@standalone":
                                reader.Read();
                                standalone = reader.Value.ToString();
                                break;

                            default:
                                throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value);
                            }
                        }

                        XmlDeclaration declaration = document.CreateXmlDeclaration(version, encoding, standalone);
                        currentNode.AppendChild(declaration);
                    }
                    else
                    {
                        XmlProcessingInstruction instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString());
                        currentNode.AppendChild(instruction);
                    }
                }
                else
                {
                    // deserialize xml element
                    bool   finishedAttributes = false;
                    bool   finishedElement    = false;
                    string elementPrefix      = GetPrefix(propertyName);
                    Dictionary <string, string> attributeNameValues = new Dictionary <string, string>();

                    // a string token means the element only has a single text child
                    if (reader.TokenType != JsonToken.String &&
                        reader.TokenType != JsonToken.Null &&
                        reader.TokenType != JsonToken.Boolean &&
                        reader.TokenType != JsonToken.Integer &&
                        reader.TokenType != JsonToken.Float &&
                        reader.TokenType != JsonToken.Date &&
                        reader.TokenType != JsonToken.StartConstructor)
                    {
                        // read properties until first non-attribute is encountered
                        while (!finishedAttributes && !finishedElement && reader.Read())
                        {
                            switch (reader.TokenType)
                            {
                            case JsonToken.PropertyName:
                                string attributeName = reader.Value.ToString();

                                if (attributeName[0] == '@')
                                {
                                    attributeName = attributeName.Substring(1);
                                    reader.Read();
                                    string attributeValue = reader.Value.ToString();
                                    attributeNameValues.Add(attributeName, attributeValue);

                                    string namespacePrefix;

                                    if (IsNamespaceAttribute(attributeName, out namespacePrefix))
                                    {
                                        manager.AddNamespace(namespacePrefix, attributeValue);
                                    }
                                }
                                else
                                {
                                    finishedAttributes = true;
                                }
                                break;

                            case JsonToken.EndObject:
                                finishedElement = true;
                                break;

                            default:
                                throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType);
                            }
                        }
                    }

                    // have to wait until attributes have been parsed before creating element
                    // attributes may contain namespace info used by the element
                    XmlElement element = (!string.IsNullOrEmpty(elementPrefix))
                    ? document.CreateElement(propertyName, manager.LookupNamespace(elementPrefix))
                    : document.CreateElement(propertyName);

                    currentNode.AppendChild(element);

                    // add attributes to newly created element
                    foreach (KeyValuePair <string, string> nameValue in attributeNameValues)
                    {
                        string attributePrefix = GetPrefix(nameValue.Key);

                        XmlAttribute attribute = (!string.IsNullOrEmpty(attributePrefix))
                      ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix))
                      : document.CreateAttribute(nameValue.Key);

                        attribute.Value = nameValue.Value;

                        element.SetAttributeNode(attribute);
                    }

                    if (reader.TokenType == JsonToken.String)
                    {
                        element.AppendChild(document.CreateTextNode(reader.Value.ToString()));
                    }
                    else if (reader.TokenType == JsonToken.Integer)
                    {
                        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((long)reader.Value)));
                    }
                    else if (reader.TokenType == JsonToken.Float)
                    {
                        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((double)reader.Value)));
                    }
                    else if (reader.TokenType == JsonToken.Boolean)
                    {
                        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((bool)reader.Value)));
                    }
                    else if (reader.TokenType == JsonToken.Date)
                    {
                        DateTime d = (DateTime)reader.Value;
                        element.AppendChild(document.CreateTextNode(XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind))));
                    }
                    else if (reader.TokenType == JsonToken.Null)
                    {
                        // empty element. do nothing
                    }
                    else
                    {
                        // finished element will have no children to deserialize
                        if (!finishedElement)
                        {
                            manager.PushScope();

                            DeserializeNode(reader, document, manager, element);

                            manager.PopScope();
                        }
                    }
                }
                break;
            }
        }
Example #8
0
 public void InnerAndOuterXml()
 {
     whitespace = doc2.CreateWhitespace("\r\n\t ");
     Assert.AreEqual(String.Empty, whitespace.InnerXml);
     Assert.AreEqual("\r\n\t ", whitespace.OuterXml);
 }
Example #9
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("slimport <mainprojectfile> <lang>:<languageimportfile>");
                Environment.Exit(1);
            }

            var logger           = new ConsoleLogger();
            var languageArgument = args[1];
            var importProjects   = new Dictionary <string, SisulizerProject>();

            foreach (var languageCommandLineArgument in args.Where(x => x.Contains("=")))
            {
                var languageArgumentParts = languageCommandLineArgument.Split("=");
                var language           = languageArgumentParts[0];
                var languageImportFile = languageArgumentParts[1];
                var importProject      = new SisulizerProject(languageImportFile, language);
                importProjects.Add(language, importProject);
            }

            var mainProjectFileName = args[0];
            var mainProject         = new XmlDocument();

            mainProject.Load(mainProjectFileName);
            foreach (XmlElement rowNode in mainProject.SelectNodes("//document/source/node/node/row"))
            {
                var context = SisulizerProject.GetContextOfNode(rowNode);
                logger.SetContext(context);
                foreach (var(language, importProject) in importProjects)
                {
                    var langRow = importProject.GetLangRow(context);
                    if (langRow != null)
                    {
                        var existingLangNode = rowNode.ChildNodes.Cast <XmlNode>().FirstOrDefault(x => x.Name == "lang" && x.Attributes["id"].Value == language);
                        if (existingLangNode != null)
                        {
                            // update
                            UpdateNode(existingLangNode, langRow, logger);
                        }
                        else
                        {
                            // append
                            if (rowNode.ChildNodes.OfType <XmlNode>().Any(x => x.NodeType == XmlNodeType.Text))
                            {
                                var nativeText = rowNode.InnerText;
                                rowNode.InnerText = string.Empty;
                                rowNode.AppendChild(mainProject.CreateWhitespace(Environment.NewLine));
                                var nativeElement = mainProject.CreateElement("native");
                                nativeElement.InnerText = nativeText;
                                rowNode.AppendChild(nativeElement);
                            }

                            rowNode.AppendChild(mainProject.CreateWhitespace(Environment.NewLine));
                            var newLangNode = mainProject.CreateElement("lang");
                            newLangNode.SetOrUpdateAttribute("id", language, logger);
                            UpdateNode(newLangNode, langRow, logger);
                            rowNode.AppendChild(newLangNode);
                            rowNode.AppendChild(mainProject.CreateWhitespace(Environment.NewLine));
                        }
                    }
                }
            }

            var xmlWriterSettings = new XmlWriterSettings();

            xmlWriterSettings.Encoding         = Encoding.UTF8;
            xmlWriterSettings.Indent           = true;
            xmlWriterSettings.IndentChars      = "  ";
            xmlWriterSettings.ConformanceLevel = ConformanceLevel.Document;
            xmlWriterSettings.CloseOutput      = true;
            xmlWriterSettings.NewLineChars     = Environment.NewLine;
            var xmlWriter = XmlWriter.Create(@"c:\externalprojects\slimport\demos\newimport.slp", xmlWriterSettings);

            mainProject.Save(xmlWriter);
            xmlWriter.Flush();
        }
Example #10
0
        void CopyNode(XmlDocument newDoc, XmlNode from, XmlNode toParent)
        {
            if (RemoveAll && from.NodeType != XmlNodeType.Element)
            {
                return;
            }

            XmlNode child       = null;
            bool    newLineNode = false;

            switch (from.NodeType)
            {
            case XmlNodeType.Element:
                newLineNode = true;
                if (RemoveNamespacesAndPrefixes)
                {
                    child = newDoc.CreateElement(from.LocalName);
                }
                else
                {
                    XmlElement e = from as XmlElement;
                    child = newDoc.CreateElement(e.Prefix, e.LocalName, e.NamespaceURI);
                }
                break;

            case XmlNodeType.Attribute: {
                if (RemoveAttributes)
                {
                    return;
                }

                XmlAttribute fromAttr = from as XmlAttribute;
                if (!fromAttr.Specified)
                {
                    return;
                }

                XmlAttribute a;

                if (RemoveNamespacesAndPrefixes)
                {
                    a = newDoc.CreateAttribute(fromAttr.LocalName);
                }
                else
                {
                    a = newDoc.CreateAttribute(fromAttr.Prefix, fromAttr.LocalName, fromAttr.NamespaceURI);
                }

                toParent.Attributes.Append(a);
                CopyNodes(newDoc, from, a);
                return;
            }

            case XmlNodeType.CDATA:
                newLineNode = true;
                child       = newDoc.CreateCDataSection((from as XmlCDataSection).Data);
                break;

            case XmlNodeType.Comment:
                if (RemoveWhiteSpace)
                {
                    return;
                }
                newLineNode = true;
                child       = newDoc.CreateComment((from as XmlComment).Data);
                break;

            case XmlNodeType.ProcessingInstruction:
                newLineNode = true;
                XmlProcessingInstruction pi = from as XmlProcessingInstruction;
                child = newDoc.CreateProcessingInstruction(pi.Target, pi.Data);
                break;

            case XmlNodeType.DocumentType:
                newLineNode = true;
                toParent.AppendChild(from.CloneNode(true));
                return;

            case XmlNodeType.EntityReference:
                child = newDoc.CreateEntityReference((from as XmlEntityReference).Name);
                break;

            case XmlNodeType.SignificantWhitespace:
                if (RemoveWhiteSpace)
                {
                    return;
                }
                child = newDoc.CreateSignificantWhitespace(from.Value);
                break;

            case XmlNodeType.Text:
                if (RemoveText)
                {
                    return;
                }
                newLineNode = true;
                child       = newDoc.CreateTextNode(from.Value);
                break;

            case XmlNodeType.Whitespace:
                if (RemoveWhiteSpace)
                {
                    return;
                }
                child = newDoc.CreateWhitespace(from.Value);
                break;

            case XmlNodeType.XmlDeclaration:
                newLineNode = true;
                XmlDeclaration d  = from as XmlDeclaration;
                XmlDeclaration d1 = newDoc.CreateXmlDeclaration(d.Version, d.Encoding, d.Standalone);
                newDoc.InsertBefore(d1, newDoc.DocumentElement);
                return;
            }
            if (NewLines && newLineNode && toParent.NodeType != XmlNodeType.Attribute)
            {
                XmlSignificantWhitespace s = newDoc.CreateSignificantWhitespace("\r\n");
                toParent.AppendChild(s);
            }
            toParent.AppendChild(child);
            CopyNodes(newDoc, from, child);
        }
Example #11
0
        /// <summary>
        /// Adds a ProjectElement to the Xml tree
        /// </summary>
        /// <param name="child">A child to add to the Xml tree, which has already been added to the ProjectElement tree</param>
        /// <remarks>
        /// The MSBuild construction APIs keep a tree of ProjectElements and a parallel Xml tree which consists of
        /// objects from System.Xml.  This is a helper method which adds an XmlElement or Xml attribute to the Xml
        /// tree after the corresponding ProjectElement has been added to the construction API tree, and fixes up
        /// whitespace as necessary.
        /// </remarks>
        internal void AddToXml(ProjectElement child)
        {
            if (child.ExpressedAsAttribute)
            {
                // todo children represented as attributes need to be placed in order too
                //  Assume that the name of the child has already been validated to conform with rules in XmlUtilities.VerifyThrowArgumentValidElementName

                //  Make sure we're not trying to add multiple attributes with the same name
                ProjectErrorUtilities.VerifyThrowInvalidProject(!XmlElement.HasAttribute(child.XmlElement.Name),
                                                                XmlElement.Location, "InvalidChildElementDueToDuplication", child.XmlElement.Name, ElementName);

                SetElementAsAttributeValue(child);
            }
            else
            {
                //  We want to add the XmlElement to the same position in the child list as the corresponding ProjectElement.
                //  Depending on whether the child ProjectElement has a PreviousSibling or a NextSibling, we may need to
                //  use the InsertAfter, InsertBefore, or AppendChild methods to add it in the right place.
                //
                //  Also, if PreserveWhitespace is true, then the elements we add won't automatically get indented, so
                //  we try to match the surrounding formatting.

                // Siblings, in either direction in the linked list, may be represented either as attributes or as elements.
                // Therefore, we need to traverse both directions to find the first sibling of the same type as the one being added.
                // If none is found, then the node being added is inserted as the only node of its kind

                ProjectElement             referenceSibling;
                Predicate <ProjectElement> siblingIsSameAsChild = _ => _.ExpressedAsAttribute == false;

                if (TrySearchLeftSiblings(child.PreviousSibling, siblingIsSameAsChild, out referenceSibling))
                {
                    //  Add after previous sibling
                    XmlElement.InsertAfter(child.XmlElement, referenceSibling.XmlElement);
                    if (XmlDocument.PreserveWhitespace)
                    {
                        //  Try to match the surrounding formatting by checking the whitespace that precedes the node we inserted
                        //  after, and inserting the same whitespace between the previous node and the one we added
                        if (referenceSibling.XmlElement.PreviousSibling != null &&
                            referenceSibling.XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                        {
                            var newWhitespaceNode = XmlDocument.CreateWhitespace(referenceSibling.XmlElement.PreviousSibling.Value);
                            XmlElement.InsertAfter(newWhitespaceNode, referenceSibling.XmlElement);
                        }
                    }
                }
                else if (TrySearchRightSiblings(child.NextSibling, siblingIsSameAsChild, out referenceSibling))
                {
                    //  Add as first child
                    XmlElement.InsertBefore(child.XmlElement, referenceSibling.XmlElement);

                    if (XmlDocument.PreserveWhitespace)
                    {
                        //  Try to match the surrounding formatting by checking the whitespace that precedes where we inserted
                        //  the new node, and inserting the same whitespace between the node we added and the one after it.
                        if (child.XmlElement.PreviousSibling != null &&
                            child.XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                        {
                            var newWhitespaceNode = XmlDocument.CreateWhitespace(child.XmlElement.PreviousSibling.Value);
                            XmlElement.InsertBefore(newWhitespaceNode, referenceSibling.XmlElement);
                        }
                    }
                }
                else
                {
                    //  Add as only child
                    XmlElement.AppendChild(child.XmlElement);

                    if (XmlDocument.PreserveWhitespace)
                    {
                        //  Try to match the surrounding formatting and add one indentation level
                        if (XmlElement.FirstChild.NodeType == XmlNodeType.Whitespace)
                        {
                            //  This container had a whitespace node, which should generally be a newline and the indent
                            //  before the closing tag.  So we add the default indentation to it so the child will now be indented
                            //  further, and then create a new whitespace node after the child so the closing tag will be on
                            //  a new line with the same indentation.
                            //  If the whitespace we end up copying isn't actually (newline + indentation) like we expect, then it
                            //  should still be OK to copy it, as we'll still be trying to match the surrounding formatting.
                            string whitespace = XmlElement.FirstChild.Value;
                            XmlElement.FirstChild.Value = whitespace + DEFAULT_INDENT;
                            var newWhitespaceNode = XmlDocument.CreateWhitespace(whitespace);
                            XmlElement.InsertAfter(newWhitespaceNode, child.XmlElement);
                        }
                        else if (XmlElement.PreviousSibling != null &&
                                 XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                        {
                            //  This container didn't have any whitespace in it.  This probably means it didn't have separate open
                            //  and close tags.  So add a whitespace node before the new child with additional indentation over the
                            //  container's indentation, and add a whitespace node with the same level of indentation as the container
                            //  after the new child so the closing tag will be indented properly.
                            string parentWhitespace       = XmlElement.PreviousSibling.Value;
                            var    indentedWhitespaceNode = XmlDocument.CreateWhitespace(parentWhitespace + DEFAULT_INDENT);
                            XmlElement.InsertBefore(indentedWhitespaceNode, child.XmlElement);
                            var unindentedWhitespaceNode = XmlDocument.CreateWhitespace(parentWhitespace);
                            XmlElement.InsertAfter(unindentedWhitespaceNode, child.XmlElement);
                        }
                    }
                }
            }
        }
Example #12
0
        /// <summary>
        /// 将当前控件的Items值保存到历史记录文件中。
        /// </summary>
        /// <param name="logFullPath"></param>
        /// <param name="TagName"></param>
        private void YESaveXmlLog(string logFullPath, string TagName)
        {
            try
            {
                //创建一个XML对象
                XmlDocument xmlDoc = new XmlDocument();

                //已经存在现成文件,则加载数据。
                if (File.Exists(logFullPath))
                {
                    xmlDoc.Load(logFullPath);
                }

                XmlElement xmlRoot = xmlDoc.DocumentElement;

                if (xmlRoot == null)
                {
                    #region 初始化XML文件
                    //加入XML声明。
                    xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes"));

                    //加入XML注释。
                    xmlDoc.AppendChild(xmlDoc.CreateComment(comment));

                    //加入空行。
                    xmlDoc.AppendChild(xmlDoc.CreateWhitespace(" \n"));

                    //创建一个根节点(带命名空间)
                    xmlRoot = xmlDoc.CreateElement("YEControl", "ComboBox"
                                                   , "http://www.clesoft.cn");

                    xmlDoc.AppendChild(xmlRoot);
                    #endregion
                }

                //将原有的节点去掉,
                XmlNodeList xnl = xmlRoot.GetElementsByTagName(TagName);
                if (xnl.Count != 0)
                {
                    xmlRoot.RemoveChild(xnl[0]);
                }

                //然后再添加新的节点。
                XmlElement xeLog = xmlDoc.CreateElement(TagName);
                xmlRoot.AppendChild(xeLog);

                //遍历每一项写入配置。
                XmlElement xeTemp = null;
                foreach (object tmp in this.Items)
                {
                    xeTemp = xmlDoc.CreateElement("log");

                    xeTemp.InnerText = tmp.ToString();

                    xeLog.AppendChild(xeTemp);
                }

                //将配置写入到文件。
                xmlDoc.Save(logFullPath);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Print(ex.ToString());
            }
        }
 public CreatorIssuer _0004(string key)
 {
     //Discarded unreachable code: IL_0002
     //IL_0003: Incompatible stack heights: 0 vs 1
     return(new ValPropertyStruct(tagIssuer.CreateWhitespace(key)));
 }
Example #14
0
        internal static void GenerateExclude()
        {
            // In case our temp ItemGroup got left there due to the build process not fully completing or whatever
            // else have you, just remove it again so we know we're clean.
            GenerateRestore();

            string[] resxFilesToExclude = Directory
                                          .GetFiles(Core.ALProjectPath, "*.resx", SearchOption.AllDirectories)
                                          .Where(x => !Path.GetFileName(x).EqualsI("Resources.resx")).ToArray();

            const string embeddedResourceName = "EmbeddedResource";
            const string conditionString      = "'$(Configuration)' != 'Debug'";
            const string conditionName        = "Condition";
            const string removeName           = "Remove";

            var xml = new XmlDocument {
                PreserveWhitespace = true
            };

            xml.Load(Core.ALProjectFile);

            var newNodes = new List <XmlNode>();

            XmlNode projNode = xml.GetElementsByTagName("Project")[0];

            XmlElement tempItemGroup = xml.CreateElement(_itemGroupName);

            foreach (string exclude in resxFilesToExclude)
            {
                XmlElement excludeElem = xml.CreateElement(embeddedResourceName);
                var        condAttr    = xml.CreateAttribute(conditionName);
                condAttr.Value = conditionString;
                var removeAttr = xml.CreateAttribute(removeName);
                removeAttr.Value = exclude.Substring(Core.ALProjectPath.Length).TrimStart('/', '\\');
                excludeElem.SetAttributeNode(condAttr);
                excludeElem.SetAttributeNode(removeAttr);

                newNodes.Add(excludeElem);
            }

            for (int i = 0; i < newNodes.Count; i++)
            {
                XmlNode n = newNodes[i];
                tempItemGroup.PrependChild(n);
                // We have to manually add linebreaks and indents
                tempItemGroup.InsertBefore(xml.CreateWhitespace("    "), n);
                tempItemGroup.InsertAfter(xml.CreateWhitespace("\r\n"), n);
            }
            // Prepend in reverse order
            tempItemGroup.PrependChild(xml.CreateWhitespace("\r\n"));
            tempItemGroup.PrependChild(xml.CreateComment("\r\n" +
                                                         "        This is a temporary ItemGroup generated by FenGen to exclude .resx files on compile.\r\n" +
                                                         "        If you can see this, something probably went wrong and you should delete this item group\r\n" +
                                                         "        to prevent crashes and chaotic behavior when editing forms.\r\n    "));
            tempItemGroup.PrependChild(xml.CreateWhitespace("\r\n    "));
            tempItemGroup.PrependChild(xml.CreateComment(GenAttributes.FenGenExcludeResx));
            tempItemGroup.PrependChild(xml.CreateWhitespace("\r\n    "));

            projNode.PrependChild(tempItemGroup);
            projNode.PrependChild(xml.CreateWhitespace("\r\n"));

            WriteXml(xml);
        }
        private bool WriteConfigFile(string bindingRedirects, bool assert)
        {
            if (!File.Exists(ExpectedConfigFilePath))
            {
                if (string.IsNullOrEmpty(bindingRedirects))
                {
                    return(false);
                }
                if (assert)
                {
                    throw new ApplicationException($"{ExpectedConfigFilePath} is expected to have some assembly binding redirects, but it does not exist.");
                }
                WriteNewConfigFile(bindingRedirects, assert);
                return(true);
            }

            var doc = new XmlDocument
            {
                PreserveWhitespace = true
            };

            doc.Load(ExpectedConfigFilePath);
            var nsmgr = new XmlNamespaceManager(doc.NameTable);

            nsmgr.AddNamespace("b", ASSEMBLY_BINDING_XMLNS);
            var assemblyBinding = doc.SelectSingleNode("/configuration/runtime/b:assemblyBinding", nsmgr);

            if (assemblyBinding == null)
            {
                if (bindingRedirects.Length == 0)
                {
                    return(false);
                }
                if (assert)
                {
                    throw new ApplicationException($"{ExpectedConfigFilePath} is expected to have some assembly binding redirects, but it has none.");
                }

                var cfg = doc.SelectSingleNode("/configuration");
                if (cfg == null)
                {
                    WriteNewConfigFile(bindingRedirects, assert);
                    return(true);
                }

                var runtime = cfg.ChildNodes.Cast <XmlNode>().FirstOrDefault(n => n.LocalName == "runtime");
                if (runtime == null)
                {
                    cfg.AppendChild(doc.CreateWhitespace("  "));
                    runtime = cfg.AppendChild(doc.CreateElement("runtime"));
                    runtime.AppendChild(doc.CreateWhitespace(Environment.NewLine + "  "));
                    cfg.AppendChild(doc.CreateWhitespace(Environment.NewLine));
                }
                assemblyBinding = runtime.ChildNodes.Cast <XmlNode>().FirstOrDefault(n => n.LocalName == "assemblyBinding");
                if (assemblyBinding == null)
                {
                    runtime.AppendChild(doc.CreateWhitespace("  "));
                    assemblyBinding = runtime.AppendChild(doc.CreateElement("assemblyBinding", ASSEMBLY_BINDING_XMLNS));
                    var attr = doc.CreateAttribute("xmlns", "http://www.w3.org/2000/xmlns/");
                    attr.Value = ASSEMBLY_BINDING_XMLNS;
                    assemblyBinding.Attributes.Append(attr);
                    runtime.AppendChild(doc.CreateWhitespace(Environment.NewLine + "  "));
                }
            }

            var newInnerXml = Environment.NewLine +
                              bindingRedirects +
                              Environment.NewLine + "    ";
            var curInnerXml = assemblyBinding.OuterXml
                              .Replace(@"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">", "")
                              .Replace(@"</assemblyBinding>", "");

            if (assert)
            {
                if (curInnerXml == newInnerXml)
                {
                    return(false);
                }
                throw new ApplicationException($"{ExpectedConfigFilePath} does not have the expected set of binding redirects.");
            }

            if (curInnerXml != newInnerXml)
            {
                assemblyBinding.InnerXml = newInnerXml;
                using var writer         = XmlWriter.Create(ExpectedConfigFilePath, s_xmlWriterSettings);
                doc.Save(writer);
            }

            return(true);
        }
Example #16
0
 /// <summary>
 /// Creates an System.Xml.XmlWhitespace node.
 /// </summary>
 /// <param name="text">The string must contain only the following characters #20; #10; #13; and #9;.</param>
 /// <returns>A new XmlWhitespace node.</returns>
 public XmlWhitespace CreateWhitespace(System.String text)
 {
     return(xmlDocument.CreateWhitespace(text));
 }
Example #17
0
        /// <summary>
        /// Creates, updates and inserts a node.
        /// </summary>
        private void InsertNode(XmlNode anchor, IUpdateOperation updateOperation)
        {
            // create node according to type
            XmlNode newXmlNode;

            switch (GetNodeType())
            {
            case XmlNodeType.Attribute:
                newXmlNode = XmlDocument.CreateAttribute(Name, Namespace ?? string.Empty);
                break;

            case XmlNodeType.Element:
                newXmlNode = XmlDocument.CreateElement(Name, Namespace ?? string.Empty);
                break;

            case XmlNodeType.CData:
                newXmlNode = XmlDocument.CreateCDataSection(string.Empty);
                break;

            case XmlNodeType.Comment:
                newXmlNode = XmlDocument.CreateComment(string.Empty);
                break;

            case XmlNodeType.SignificantWhitespace:
                newXmlNode = XmlDocument.CreateSignificantWhitespace(string.Empty);
                break;

            case XmlNodeType.Text:
                newXmlNode = XmlDocument.CreateTextNode(string.Empty);
                break;

            case XmlNodeType.Whitespace:
                newXmlNode = XmlDocument.CreateWhitespace(string.Empty);
                break;

            default:
                // should not happen
                throw new ArgumentOutOfRangeException();
            }

            // update node with input
            updateOperation.Update(newXmlNode);

            // insert node relative to anchor
            if (newXmlNode is XmlAttribute)
            {
                var newXmlAttribute = (XmlAttribute)newXmlNode;
                switch (GetNodePosition())
                {
                case XmlNodePosition.Append:
                case XmlNodePosition.After:
                    if (anchor is XmlAttribute)
                    {
                        var xmlAttribute = (XmlAttribute)anchor;
                        if (xmlAttribute.OwnerElement != null)
                        {
                            xmlAttribute.OwnerElement.Attributes.InsertAfter(newXmlAttribute, xmlAttribute);
                        }
                    }
                    else if (anchor.Attributes != null)
                    {
                        anchor.Attributes.Append(newXmlAttribute);
                    }
                    break;

                case XmlNodePosition.Prepend:
                case XmlNodePosition.Before:
                    if (anchor is XmlAttribute)
                    {
                        var xmlAttribute = (XmlAttribute)anchor;
                        if (xmlAttribute.OwnerElement != null)
                        {
                            xmlAttribute.OwnerElement.Attributes.InsertBefore(newXmlAttribute, xmlAttribute);
                        }
                    }
                    else if (anchor.Attributes != null)
                    {
                        anchor.Attributes.Prepend(newXmlAttribute);
                    }
                    break;

                default:
                    // should not happen
                    throw new ArgumentOutOfRangeException();
                }
            }
            else
            {
                switch (GetNodePosition())
                {
                case XmlNodePosition.Append:
                    anchor.AppendChild(newXmlNode);
                    break;

                case XmlNodePosition.Prepend:
                    anchor.PrependChild(newXmlNode);
                    break;

                case XmlNodePosition.After:
                    if (anchor.ParentNode != null)
                    {
                        anchor.ParentNode.InsertAfter(newXmlNode, anchor);
                    }
                    break;

                case XmlNodePosition.Before:
                    if (anchor.ParentNode != null)
                    {
                        anchor.ParentNode.InsertBefore(newXmlNode, anchor);
                    }
                    break;

                default:
                    // should not happen
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
        private void LoadDocument()
        {
            bool       preserveWhitespace = false;
            XmlReader  r      = this.reader;
            XmlNode    parent = this.doc;
            XmlElement element;

            while (r.Read())
            {
                XmlNode node = null;
                switch (r.NodeType)
                {
                case XmlNodeType.Element:
                    bool fEmptyElement = r.IsEmptyElement;
                    element = doc.CreateElement(r.Prefix, r.LocalName, r.NamespaceURI);

                    AddToTable(element);
                    element.IsEmpty = fEmptyElement;
                    ReadAttributes(r, element);

                    if (!fEmptyElement)
                    {
                        parent.AppendChild(element);
                        parent = element;
                        continue;
                    }
                    node = element;
                    break;

                case XmlNodeType.EndElement:
                    if (parent.ParentNode == null)
                    {
                        // syntax error in document.
                        IXmlLineInfo li = (IXmlLineInfo)r;
                        throw new XmlException(string.Format(SR.UnexpectedToken,
                                                             "</" + r.LocalName + ">", li.LineNumber, li.LinePosition), null, li.LineNumber, li.LinePosition);
                    }
                    parent = parent.ParentNode;
                    continue;

                case XmlNodeType.EntityReference:
                    if (r.CanResolveEntity)
                    {
                        r.ResolveEntity();
                    }
                    continue;

                case XmlNodeType.EndEntity:
                    continue;

                case XmlNodeType.Attribute:
                    node = LoadAttributeNode();
                    break;

                case XmlNodeType.Text:
                    node = doc.CreateTextNode(r.Value);
                    AddToTable(node);
                    break;

                case XmlNodeType.SignificantWhitespace:
                    node = doc.CreateSignificantWhitespace(r.Value);
                    AddToTable(node);
                    break;

                case XmlNodeType.Whitespace:
                    if (preserveWhitespace)
                    {
                        node = doc.CreateWhitespace(r.Value);
                        AddToTable(node);
                        break;
                    }
                    else
                    {
                        continue;
                    }

                case XmlNodeType.CDATA:
                    node = doc.CreateCDataSection(r.Value);
                    AddToTable(node);
                    break;

                case XmlNodeType.XmlDeclaration:
                    node = LoadDeclarationNode();
                    break;

                case XmlNodeType.ProcessingInstruction:
                    node = doc.CreateProcessingInstruction(r.Name, r.Value);
                    AddToTable(node);
                    if (string.IsNullOrEmpty(this.xsltFileName) && r.Name == "xml-stylesheet")
                    {
                        string href = ParseXsltArgs(((XmlProcessingInstruction)node).Data);
                        if (!string.IsNullOrEmpty(href))
                        {
                            this.xsltFileName = href;
                        }
                    }
                    break;

                case XmlNodeType.Comment:
                    node = doc.CreateComment(r.Value);
                    AddToTable(node);
                    break;

                case XmlNodeType.DocumentType: {
                    string pubid = r.GetAttribute("PUBLIC");
                    string sysid = r.GetAttribute("SYSTEM");
                    node = doc.CreateDocumentType(r.Name, pubid, sysid, r.Value);
                    break;
                }

                default:
                    UnexpectedNodeType(r.NodeType);
                    break;
                }

                Debug.Assert(node != null);
                Debug.Assert(parent != null);
                if (parent != null)
                {
                    parent.AppendChild(node);
                }
            }
        }
Example #19
0
 public void XmlWhitespaceBadConstructor()
 {
     broken = document.CreateWhitespace("black");
 }
Example #20
0
        /// <summary>
        /// Adds a ProjectElement to the Xml tree
        /// </summary>
        /// <param name="child">A child to add to the Xml tree, which has already been added to the ProjectElement tree</param>
        /// <remarks>
        /// The MSBuild construction APIs keep a tree of ProjectElements and a parallel Xml tree which consists of
        /// objects from System.Xml.  This is a helper method which adds an XmlElement or Xml attribute to the Xml
        /// tree after the corresponding ProjectElement has been added to the construction API tree, and fixes up
        /// whitespace as necessary.
        /// </remarks>
        internal void AddToXml(ProjectElement child)
        {
            if (child.ExpressedAsAttribute)
            {
                // todo children represented as attributes need to be placed in order too
                //  Assume that the name of the child has already been validated to conform with rules in XmlUtilities.VerifyThrowArgumentValidElementName

                //  Make sure we're not trying to add multiple attributes with the same name
                ProjectErrorUtilities.VerifyThrowInvalidProject(!XmlElement.HasAttribute(child.XmlElement.Name),
                                                                XmlElement.Location, "InvalidChildElementDueToDuplication", child.XmlElement.Name, ElementName);

                SetElementAsAttributeValue(child);
            }
            else
            {
                //  We want to add the XmlElement to the same position in the child list as the corresponding ProjectElement.
                //  Depending on whether the child ProjectElement has a PreviousSibling or a NextSibling, we may need to
                //  use the InsertAfter, InsertBefore, or AppendChild methods to add it in the right place.
                //
                //  Also, if PreserveWhitespace is true, then the elements we add won't automatically get indented, so
                //  we try to match the surrounding formatting.

                // Siblings, in either direction in the linked list, may be represented either as attributes or as elements.
                // Therefore, we need to traverse both directions to find the first sibling of the same type as the one being added.
                // If none is found, then the node being added is inserted as the only node of its kind

                ProjectElement             referenceSibling;
                Predicate <ProjectElement> siblingIsExplicitElement = _ => _.ExpressedAsAttribute == false;

                if (TrySearchLeftSiblings(child.PreviousSibling, siblingIsExplicitElement, out referenceSibling))
                {
                    //  Add after previous sibling
                    XmlElement.InsertAfter(child.XmlElement, referenceSibling.XmlElement);
                    if (XmlDocument.PreserveWhitespace)
                    {
                        //  Try to match the surrounding formatting by checking the whitespace that precedes the node we inserted
                        //  after, and inserting the same whitespace between the previous node and the one we added
                        if (referenceSibling.XmlElement.PreviousSibling != null &&
                            referenceSibling.XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                        {
                            var newWhitespaceNode = XmlDocument.CreateWhitespace(referenceSibling.XmlElement.PreviousSibling.Value);
                            XmlElement.InsertAfter(newWhitespaceNode, referenceSibling.XmlElement);
                        }
                    }
                }
                else if (TrySearchRightSiblings(child.NextSibling, siblingIsExplicitElement, out referenceSibling))
                {
                    //  Add as first child
                    XmlElement.InsertBefore(child.XmlElement, referenceSibling.XmlElement);

                    if (XmlDocument.PreserveWhitespace)
                    {
                        //  Try to match the surrounding formatting by checking the whitespace that precedes where we inserted
                        //  the new node, and inserting the same whitespace between the node we added and the one after it.
                        if (child.XmlElement.PreviousSibling != null &&
                            child.XmlElement.PreviousSibling.NodeType == XmlNodeType.Whitespace)
                        {
                            var newWhitespaceNode = XmlDocument.CreateWhitespace(child.XmlElement.PreviousSibling.Value);
                            XmlElement.InsertBefore(newWhitespaceNode, referenceSibling.XmlElement);
                        }
                    }
                }
                else
                {
                    //  Add as only child
                    XmlElement.AppendChild(child.XmlElement);

                    if (XmlDocument.PreserveWhitespace)
                    {
                        //  If the empty parent has whitespace in it, delete it
                        if (XmlElement.FirstChild.NodeType == XmlNodeType.Whitespace)
                        {
                            XmlElement.RemoveChild(XmlElement.FirstChild);
                        }

                        var parentIndentation = GetElementIndentation(XmlElement);

                        var leadingWhitespaceNode  = XmlDocument.CreateWhitespace(Environment.NewLine + parentIndentation + DEFAULT_INDENT);
                        var trailingWhiteSpaceNode = XmlDocument.CreateWhitespace(Environment.NewLine + parentIndentation);

                        XmlElement.InsertBefore(leadingWhitespaceNode, child.XmlElement);
                        XmlElement.InsertAfter(trailingWhiteSpaceNode, child.XmlElement);
                    }
                }
            }
        }
 public IXmlNode CreateWhitespace(string text)
 {
     return(new XmlNodeWrapper(_document.CreateWhitespace(text)));
 }
Example #22
0
        private void button1_Click_1(object sender, EventArgs e)
        {
            for (int i = 0; i < confList.Count; i++)
            {
                switch (confList.ElementAt(i).Key)
                {
                case "Server":
                    confList["Server"] = textBox1.Text;
                    break;

                case "Username":
                    confList["Username"] = textBox2.Text;
                    break;

                case "Password":
                    confList["Password"] = textBox3.Text;
                    break;

                case "ClientF":
                    confList["ClientF"] = textBox4.Text;
                    break;

                case "Service":
                    if (checkBox2.Checked)
                    {
                        confList["Service"] = "1";
                    }
                    else
                    {
                        confList["Service"] = "0";
                    }
                    break;

                case "IntH":
                    confList["IntH"] = textBox5.Text;
                    break;

                case "Fpath":
                    confList["Fpath"] = textBox9.Text;
                    break;

                case "IntM":
                    confList["IntM"] = textBox6.Text;
                    break;

                case "IntS":
                    confList["IntS"] = textBox7.Text;
                    break;

                case "Cleanup":
                    confList["Cleanup"] = textBox10.Text;
                    break;

                case "Keep":
                    confList["Keep"] = textBox11.Text;
                    break;

                case "ClName":
                    confList["ClName"] = textBox13.Text;
                    break;

                case "Level":
                    if (radioButton3.Checked)
                    {
                        confList["Level"] = "0";
                    }
                    else
                    {
                        confList["Level"] = "1";
                    }
                    break;

                default:
                    break;
                }
            }



            XmlDocument doc = new XmlDocument();

            doc.PreserveWhitespace = true;
            doc.Load(AppContext.BaseDirectory + "\\config.xml");
            XmlNodeList setings = doc.GetElementsByTagName("appSettings");

            if (setings.Count > 0)
            {
                doc.GetElementsByTagName("appSettings").Item(0).RemoveAll();
            }
            foreach (var elem in confList)
            {
                XmlNode newnode = doc.CreateNode(XmlNodeType.Element, "add", null);
                //Create a new attribute
                XmlAttribute attr1 = doc.CreateAttribute("key");
                attr1.Value = elem.Key;

                XmlAttribute attr2 = doc.CreateAttribute("value");
                attr2.Value = elem.Value;

                //Add the attribute to the node
                newnode.Attributes.SetNamedItem(attr1);
                newnode.Attributes.SetNamedItem(attr2);
                XmlWhitespace ws = doc.CreateWhitespace("\r\n\t");
                doc.GetElementsByTagName("appSettings").Item(0).AppendChild(ws);
                doc.GetElementsByTagName("appSettings").Item(0).AppendChild(newnode);
            }
            XmlWhitespace wse = doc.CreateWhitespace("\r\n");

            doc.GetElementsByTagName("appSettings").Item(0).AppendChild(wse);
            doc.PreserveWhitespace = true;
            doc.Save(AppContext.BaseDirectory + "\\config.xml");

            logs           = "All params were saved...";
            textBox8.Text += logs + Environment.NewLine;
            saveLog(logs);
            logs = "";

            button4.Enabled = true;

            timer3.Interval = Convert.ToInt32(confList["Cleanup"]) * 60000;
        }
Example #23
0
        private static int Detokenize(Tuple <ArrayDiffKind, Token>[] tokens, int index, XmlElement current, XmlDocument doc)
        {
            for (; index < tokens.Length; ++index)
            {
                var token = tokens[index];
                switch (token.Item1)
                {
                case ArrayDiffKind.Same:
                case ArrayDiffKind.Added:
                    switch (token.Item2.Type)
                    {
                    case XmlNodeType.CDATA:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }
                        current.AppendChild(doc.CreateCDataSection(token.Item2.Value));
                        break;

                    case XmlNodeType.Comment:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }
                        current.AppendChild(doc.CreateComment(token.Item2.Value));
                        break;

                    case XmlNodeType.SignificantWhitespace:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }
                        current.AppendChild(doc.CreateSignificantWhitespace(token.Item2.Value));
                        break;

                    case XmlNodeType.Text:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }
                        current.AppendChild(doc.CreateTextNode(token.Item2.Value));
                        break;

                    case XmlNodeType.Whitespace:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }
                        current.AppendChild(doc.CreateWhitespace(token.Item2.Value));
                        break;

                    case XmlNodeType.Element:
                        XmlElement next = doc.CreateElement(token.Item2.Value);
                        if (current == null)
                        {
                            doc.AppendChild(next);
                        }
                        else
                        {
                            current.AppendChild(next);
                        }
                        index = Detokenize(tokens, index + 1, next, doc);
                        break;

                    case XmlNodeType.Attribute:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }
                        string[] parts = token.Item2.Value.Split(new char[] { '=' }, 2);
                        current.SetAttribute(parts[0], parts[1]);
                        break;

                    case XmlNodeType.EndElement:

                        // nothing to do
                        break;

                    case XmlNodeType.None:
                        if (current == null)
                        {
                            throw new ArgumentNullException("current");
                        }

                        // ensure we're closing the intended element
                        if (token.Item2.Value != current.Name)
                        {
                            throw new InvalidOperationException(string.Format("mismatched element ending; found </{0}>, expected </{1}>", token.Item2.Value, current.Name));
                        }

                        // we're done with this sequence
                        return(index);

                    default:
                        throw new InvalidOperationException("unhandled node type: " + token.Item2.Type);
                    }
                    break;

                case ArrayDiffKind.Removed:

                    // ignore removed nodes
                    break;

                default:
                    throw new InvalidOperationException("invalid diff kind: " + token.Item1);
                }
            }
            if (current != null)
            {
                throw new InvalidOperationException("unexpected end of tokens");
            }
            return(index);
        }
Example #24
0
        public static void Write(string file, string locale, List <DataItem> items)
        {
            Program.Write($"Writing resources for locale `{(string.IsNullOrEmpty(locale) ? "Default" : locale)}`... ");

            string indent       = Config.Indent;
            int    stringsCount = 0;

            XmlDocument doc = new XmlDocument();

            // xml declaration
            XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            XmlElement     root           = doc.DocumentElement;

            doc.InsertBefore(xmlDeclaration, root);

            XmlElement resources = doc.CreateElement(string.Empty, "resources", string.Empty);

            doc.AppendChild(resources);
            resources.AppendChild(doc.CreateTextNode(NEWLINE));

            foreach (var item in items)
            {
                // comment
                if (item.IsComment)
                {
                    resources.AppendChild(doc.CreateWhitespace(indent));
                    resources.AppendChild(doc.CreateComment($" {item.Name} "));
                    resources.AppendChild(doc.CreateTextNode(NEWLINE));
                }
                // string resource
                else
                {
                    // write empty rows if required
                    if (Config.KeepEmptyRows && item.IsEmptyRow)
                    {
                        resources.AppendChild(doc.CreateTextNode(NEWLINE));
                        continue;
                    }

                    // skip items without text
                    string value = item.Values[locale];
                    if (string.IsNullOrEmpty(value))
                    {
                        continue;
                    }

                    // skip non-translatable strings for all locales except default
                    if (!item.IsTranslatable && !String.IsNullOrEmpty(locale))
                    {
                        continue;
                    }

                    XmlElement resourceString = doc.CreateElement("string");
                    resourceString.SetAttribute("name", item.Name);

                    if (!item.IsFormatted)
                    {
                        resourceString.SetAttribute("formatted", "false");
                    }

                    if (!item.IsTranslatable)
                    {
                        resourceString.SetAttribute("translatable", "false");
                    }

                    if (!string.IsNullOrEmpty(item.Documentation))
                    {
                        resourceString.SetAttribute("documentation", item.Documentation);
                    }

                    // Escape apostrophes:
                    if (value.Contains("'"))
                    {
                        value = Regex.Replace(value, @"([^\\])(\')", @"$1\'");
                    }

                    resourceString.InnerXml = value;
                    resources.AppendChild(doc.CreateWhitespace(indent));
                    resources.AppendChild(resourceString);
                    resources.AppendChild(doc.CreateTextNode(NEWLINE));

                    stringsCount++;
                }
            }

            Program.WriteLine($"Done.", ConsoleColor.DarkGreen);
            Program.WriteLine($"({stringsCount} strings added.)\n");

            try
            {
                doc.Save(file);
            }
            catch (Exception ex)
            {
                Program.WriteLineAndExit($"Unable to save xml in file `{file}`. Reason: {ex.Message}", -1, ConsoleColor.Red);
            }
        }