Reputation: 3567
I have an XmlWriter as follows
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineHandling = NewLineHandling.Entitize;
using (XmlWriter currentWriter = XmlWriter.Create(filePath, settings))
{
workingXmlDocument.WriteTo(currentWriter);
currentWriter.Flush();
} // using (XmlWriter xw = XmlWriter.Create(FilePath))
I have programmatically created an Xml Document that I am trying to write with this, and it is writting just fine, except that I have a block of elements that are created in a loop and it is putting all these elements onto one line. If you need to see any other code from the program let me know and I can put it here. I welcome any ideas even if they aren't full solutions.
Update - the complete method where the problem is happening
private void XMLReaderUtil(string filePath)
{
XDocument workingXmlDocument;
using (XmlReader currentReader = XmlReader.Create(filePath))
{
workingXmlDocument = XDocument.Load(currentReader);
foreach (KeyValuePair<string, string> currentIteration in logDataRaw)
{
FileInfo currentEntry = new FileInfo(currentIteration.Value);
string testString = currentEntry.Directory.Name;
if (testString.Contains(" ")) { testString = testString.Replace(" ", "_"); }
IEnumerable<XElement> list = from XElement e in workingXmlDocument.Descendants(wixNS + testString)
select e;
DirectoryInfo temp = currentEntry.Directory;
while (list.Count() == 0 && !temp.Name.Contains(":"))
{
testString = temp.Name;
if (testString.Contains(" ")) { testString = testString.Replace(" ", "_"); }
list = from XElement e in workingXmlDocument.Descendants(wixNS + testString)
select e;
temp = temp.Parent;
} // while (list.Count() == 0 && !temp.Name.Contains(":"))
if (list.Count() == 0)
{
IEnumerable<XElement> targetDirectory =
from XElement e in workingXmlDocument.Descendants(wixNS + "Directory")
where e.Attribute("Id").Value == "TARGETDIR"
select e;
var outXml = new XElement("root");
foreach (var item in targetDirectory)
{
item.Add(new XElement(
"Directory",
new XAttribute("new", 1)));
outXml.Add(item);
}
outXml.Save(@"c:\users\adkins\desktop\temp.wxs", SaveOptions.None);
}
} // foreach (KeyValuePair<string, string> kvp in xmlDataChanged)
// return workingXmlDocument;
} // using (XmlReader sr = XmlReader.Create(FilePath))
IEnumerable<XElement> cleanup =
from XElement e in workingXmlDocument.Descendants(wixNS + "Directory")
select e;
Collection<string> keep = new Collection<string>();
XElement[] blah;
blah = cleanup.ToArray();
for (int i = 0; i < blah.Length; i++)
{
if (!keep.Contains(blah[i].Attribute("Id").Value))
{
keep.Add(blah[i].Attribute("Id").Value);
}
else
{
blah[i].Remove();
}
}
workingXmlDocument.Save(filePath, SaveOptions.None);
// XMLWriter attempt
//XmlWriterSettings settings = new XmlWriterSettings();
//settings.Indent = true;
//settings.IndentChars = "\t";
//settings.NewLineHandling = NewLineHandling.Entitize;
//settings.NewLineChars = "\n";
//settings.CloseOutput = true;
//settings.Encoding = System.Text.Encoding.UTF8;
//using (XmlWriter currentWriter = XmlWriter.Create(filePath, settings))
//{
// workingXmlDocument.WriteTo(currentWriter);
// currentWriter.Flush();
//} // using (XmlWriter xw = XmlWriter.Create(FilePath))
//TextWriter test run - nothing changed
//XmlTextWriter writer = new XmlTextWriter(filePath, System.Text.Encoding.UTF8);
//writer.Formatting = Formatting.Indented;
//writer.IndentChar = '\t';
//writer.Indentation = 1;
//workingXmlDocument.WriteTo(writer);
//writer.Flush();
//writer.Close();
}
Here is the complete problem method. It includes my attempts at various forms of saving the file. It is a complete mess due to my efforts to solve this problem and problems that I encountered before getting to this one. Any help would be greatly appreciated!
The variable "logDataRaw" is a dictionary containing the name of a file and the path to where it is stored. If you need any other clarification please let me know.
Upvotes: 1
Views: 3036
Reputation: 51
If somebody uses XDocument and still has problems with saving XML to file with correct indent this might help you, it did for me:
In addition to Chad's answer I had to use XName.Get(...) when specifying XElement name:
var xdoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(XName.Get("TranslationContainer"),
new XElement(XName.Get("Translations"))));
Check that you have a well-formatted xml (don't have text outside xml tags)
Good luck.
Upvotes: 0
Reputation: 3567
The problem was that I was loading the XML file through an XMLReader. Once I removed that and just loaded it directly into my XDocument than everything worked fine.
Upvotes: 2
Reputation: 2154
You might just need to use an XmlTextWriter with default encoding instead of XmlWriter and set the Formatting property of the Writer object to Formatting.Indented
Upvotes: 0
Reputation: 22054
Why not just use XElement.Save() instead of XmlWriter?
http://msdn.microsoft.com/en-us/library/bb538458.aspx
EDIT:
I just ran the following bit of code
var xml = new XElement("root",
new XElement("node",
new XAttribute("index", 1)
),
new XElement("node",
new XAttribute("index", 2)
),
new XElement("node",
new XAttribute("index", 3)
),
new XElement("node",
new XAttribute("index", 4)
)
);
IEnumerable<XElement> ieXml =
from XElement e in xml.Elements()
select e;
var outXml = new XElement("root");
foreach (var item in ieXml)
{
item.Add(new XElement(
"Directory",
new XAttribute("new", 1)));
outXml.Add(item);
}
outXml.Save(@"d:\foo.xml", SaveOptions.None);
and the result is formatted
<?xml version="1.0" encoding="utf-8"?>
<root>
<node index="1">
<Directory new="1" />
</node>
<node index="2">
<Directory new="1" />
</node>
<node index="3">
<Directory new="1" />
</node>
<node index="4">
<Directory new="1" />
</node>
</root>
I don't know what you're doing differently, but this works.
Upvotes: 1