c# – 如何使用XDocument.Save使用属性的自定义缩进来保存文件
我的目标是输出修改后的
XML文件并保留原始文件中存在的特殊缩进.目标是使得生成的文件看起来仍然像原始文件,使它们更容易通过源代码控制进行比较和合并.
我的程序将读取XML文件并添加或更改一个特定属性. 这是我想要实现/保留的格式: <Base Import="..commomstyle.xml"> <Item Width="480" Height="500" VAlign="Center" Style="level1header"> (...) 在这种情况下,我只希望将第一个属性与第一个属性对齐. XmlWriterSettings提供格式化选项,但它们无法实现我正在寻找的结果. settings.Indent = true; settings.NewLineOnAttributes = true; 这些设置会将第一个属性放在换行符上,而不是将其与节点保持在同一行,并将属性与节点对齐. 这是Load调用,它要求保留空格: MyXml = XDocument.Load(filepath,LoadOptions.PreserveWhitespace); 但似乎它不会达到我的预期. 我试图提供一个自定义类,它从XmlWriter派生到XDocument.Save调用,但我没有设法正确插入空格而没有遇到InvalidOperationException.再加上这个解决方案对于我正在寻找的小额外添加似乎有些过分. 作为参考,这是我的保存调用,而不是使用我的自定义xml编写器(无论如何都不起作用) XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineOnAttributes = true; settings.OmitXmlDeclaration = true; using (XmlWriter writer = XmlWriter.Create(filepath + "_auto",settings)) { MyXml.Save(writer); } 解决方法
我最终没有完全使用XDocument.Save,而是创建了一个带有XDocument,XmlWriter和TextWriter的类.
该类解析XDocument中的所有节点,TextWriter绑定到磁盘上的文件,XmlWriter将其用作输出管道. 然后我的类使用XmlWriter输出xml.为了实现额外的间距,我使用了这里描述的解决方案,https://stackoverflow.com/a/24010544/5920497,这就是我也使用底层TextWriter的原因. 这是解决方案的一个例子. 调用类来保存文档: XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineOnAttributes = false; // Behavior changed in PrettyXmlWriter settings.OmitXmlDeclaration = true; using(TextWriter rawwriter = File.CreateText(filepath)) using (XmlWriter writer = XmlWriter.Create(rawwriter,settings)) { // rawwriter is used both by XmlWriter and PrettyXmlWriter PrettyXmlWriter outputter = new PrettyXmlWriter(writer,rawwriter); outputter.Write(MyXml); writer.Flush(); writer.Close(); } 里面的PrettyXmlWriter: private XmlWriter Writer { get; set; } private TextWriter InnerTextWriter { get; set; } public void Write(XDocument doc) { XElement root = doc.Root; WriteNode(root,0); } private void WriteNode(XNode node,int currentNodeDepth) { if(node.NodeType == XmlNodeType.Element) { WriteElement((XElement)node,currentNodeDepth); } else if(node.NodeType == XmlNodeType.Text) { WriteTextNode((XText)node,currentNodeDepth,doIndentAttributes); } } private void WriteElement(XElement node,int currentNodeDepth) { Writer.WriteStartElement(node.Name.LocalName); // Write attributes with indentation XAttribute[] attributes = node.Attributes().ToArray(); if(attributes.Length > 0) { // First attribute,unindented. Writer.WriteAttributeString(attributes[0].Name.LocalName,attributes[0].Value); for(int i=1; i<attributes.Length; ++i) { // Write indentation Writer.Flush(); string indentation = Writer.Settings.NewLineChars + string.Concat(Enumerable.Repeat(Writer.Settings.IndentChars,currentNodeDepth)); indentation += string.Concat(Enumerable.Repeat(" ",node.Name.LocalName.Length + 1)); // Using Underlying TextWriter trick to output whitespace InnerTextWriter.Write(indentation); Writer.WriteAttributeString(attributes[i].Name.LocalName,attributes[i].Value); } } // output children foreach(XNode child in node.Nodes()) { WriteNode(child,currentNodeDepth + 1); } Writer.WriteEndElement(); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |