0

I want to modify a XML file but the tricky part is that the info I add should have minimal formatting. I have been searching for a while and I can't seem to find an answer. Here's what the XML looks currently (original):

<?xml version="1.0" encoding="utf-8"?>
<doe-jane>
  <name>Jane Doe</name>
  <contact>North Pole

Tel: (555) 123-4567
jane.doe@abc.com
</contact>
  <coveragelist>
    <company>Comp1</company>
    <company>Comp2</company>
  </coveragelist>
</doe-jane>

It has to look like this:

<?xml version="1.0" encoding="utf-8"?>
<doe-jane>
  <name>Jane Doe</name>
  <contact>North Pole

Tel: (555) 123-4567
jane.doe@abc.com
</contact>
--> // Change needs to happen from here on <--
<coveragelist><company>Comp1</company>
<company>Comp2</company>
</coveragelist>
</doe-jane>

Here's my code so far:

XmlDocument d = new XmlDocument();
//XmlTextWriter wr = new XmlTextWriter(resAnXFile, Encoding.UTF8);
//wr.Formatting = Formatting.None;
d.Load(resAnXFile);
XmlNode t = d.SelectSingleNode("//coveragelist");
t.ParentNode.RemoveChild(t);
// create CoverageList node
XmlNode coverageListNode = d.CreateNode(XmlNodeType.Element, "coveragelist", null);
foreach (var company in dataList)
{
    // create company nodes
    XmlNode companyNode = d.CreateElement("company");
    companyNode.InnerText = company.CompanyName.ToString();
    coverageListNode.AppendChild(companyNode);
}
d.DocumentElement.AppendChild(coverageListNode);
d.Save(resAnXFile);

I've tried XMLTextWriter but I didn't have any luck. I really appreciate any help.

Thank you in advance.

inquisitive_one
  • 1,465
  • 7
  • 32
  • 56
  • 1
    `--> // Change needs to happen from here on <--` What kind of change? Remove formatting? why at that point? – L.B May 09 '12 at 20:30
  • @L.B Yes, the special formatting should happen from that point on. Our 3rd party app has no problems with everything until that point. It has problems with the rest. Hence, my request. – inquisitive_one May 14 '12 at 18:57

3 Answers3

1

I'm a little confused as to what you're asking, but my understanding is this part:

    <company>Comp1&lt/company>
    <company>Comp2&lt/company>

is the new part, and you want it with no indents and with the first company on the same line as the starting "coveragelist" node?

I know you said you tried XmlTextWriter, but have you tried:

xmlTextWriter.Formatting = xmlTextWriter.Formatting.None

and

xmlTextWriter.WriteString("\n");

where you need?

trycatch
  • 568
  • 1
  • 8
  • 17
  • 1
    Though I agree with Henk and L.B. that whitespace should really never be a big deal in XML. If it is, you should re-investigate what you're doing. – trycatch May 09 '12 at 20:34
  • Yes, @trycatch. That's exactly what I need. I need the 1st company on the same line as "coveragelist" node. And to answer your comment about white space, a third party app is very sensitive to the white spaces so I have to remove them. Anyway, I tried your suggestion and I got: System.NullReferenceException: Object reference not set to an instance of an object. – inquisitive_one May 14 '12 at 18:55
  • My suggestion isn't complete code, it's just showing you the functions and properties you can set on xmlTextWriter that will help you produce the results you need. nullreferenceexception means you're not initializing somewhere. Declared an XmlTextWriter without a " = new XmlTextWriter()" perhaps? – trycatch May 14 '12 at 22:23
1

If your intend is to remove formatting

StringWriter wr = new StringWriter();
XDocument xDoc = XDocument.Load(.....);
xDoc.Save(wr, SaveOptions.DisableFormatting);
var newXml = wr.ToString();
L.B
  • 114,136
  • 19
  • 178
  • 224
  • I get the error: No overload method for Save takes 2 arguments. Here are the namespaces I'm using: using System; using System.Collections.Generic; using System.Linq;. Is there a namespace that i'm missing or I should remove? using System.Text; using System.Xml; using System.Xml.Xsl; using System.Xml.XPath; using System.Xml.Linq; using System.IO; – inquisitive_one May 14 '12 at 19:01
  • @inquisitive_one `System` `System.IO` and `System.Xml.Linq` are enough for this code. – L.B May 14 '12 at 19:09
0

Thank you everyone for your suggestions. With your help I was able to come up with this solution:

// Open up the same file and remove xml auto-formatting
XmlReader reader = XmlReader.Create(readFileName);
XmlTextWriter writer = new XmlTextWriter(writeFileName, null);
while (reader.Read())
{
switch (reader.NodeType)
{
    case XmlNodeType.Element:
        // if 1st node after openening tag is analyst name then setup a linefeed
        if (reader.Name.Equals(Path.GetFileNameWithoutExtension(readerFileName)))
        {
            writer.WriteStartElement(reader.Name);
            writer.WriteString("\r\n");
        }
        else
        {
            // setup linefeed after every element
            writer.WriteStartElement(reader.Name);
            writer.WriteAttributes(reader, true);
            if (reader.IsEmptyElement)
            {
                writer.WriteEndElement();
                writer.WriteString("\r\n");
            }
        }
        break;

    case XmlNodeType.Text:
        writer.WriteString(reader.Value);
        break;

    case XmlNodeType.EndElement:
        writer.WriteEndElement();
        break;

    // handles opening xml tag
    case XmlNodeType.XmlDeclaration:
    case XmlNodeType.ProcessingInstruction:
        writer.WriteProcessingInstruction(reader.Name, reader.Value);
        writer.WriteString("\r\n");
        break;
}
}
// close reader & writer
writer.Flush();
reader.Close();
inquisitive_one
  • 1,465
  • 7
  • 32
  • 56