I have a situation where I have to generate some XML files based on data that comes from DB. The structure of the data that is stored in DB is the problem. Actually all the TAGs and their values are stored in a table which also include closing TAGs as well.

For example consider the following XML that will be produced:

<x>
    <y>
        <a>cc</a>
        <b></b>
    </y>
    <y>
        <a>oo</a>
        <b>kk</b>
    </y>
</x>

Now this XML's data is stored in DB as follows:

IS_CONTAINER    TAG_NAME    TAG_VALUE
------------    --------    ---------
1               x           NULL
1               y           NULL
0               a           cc
0               b           NULL
1               /y          NULL
1               y           NULL
0               a           oo
0               b           kk
1               /y          NULL
1               /x          NULL

Here IS_CONTAINER = 1 means the TAG contains children AND its closing tag is coming in the records. Such as x & y. Where as IS_CONTAINER = 0 means it is a single XML element with no sub elements so I will have to close/append its closing TAG after setting its value. such as a & b.

I suppose I cant use XmlTextWriter as I will have to explicitly call its WriteStartElement & WriteEndElement methods everytime. It will get unnecessarily complex as I will have to keep track of which elements starts with "\" which will mean I have to close some previously opened element.

I could use TextWriter to write the data into a file as every row is read and just append "<" & ">" characters to each TAG_NAME before writing into the text file but it will also mean that I will have to write <?xml version="1.0" encoding="iso-8859-1" standalone="yes"?> myself as the very first line of the file. everything will be done manually.

I hope you know what the issue is.

Can you guys please recommend me some good way If I am missing something?

2

There are 2 answers

2
varocarbas On BEST ANSWER

The whole point of your problem is building the best algorithm to extract the DB information in the most efficient way. In principle, it seems better to rely on XmlWriter, but with the proper algorithm other alternatives might also be OK.

Sample code:

System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
settings.NewLineOnAttributes = false;
settings.Indent = true;
using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create("output.xml", settings))
{
    writer.WriteStartDocument();

    int[] IS_CONTAINER = new int[] { 1, 1, 0, 0, 1, 1 };
    string[] TAG_NAME = new string[]{ "x", "y", "a", "b", "/y", "/x"};
    string[] TAG_VALUE = new string[]{ null, null, "cc", "kk", "/y", "/x"};

    for (int i = 0; i <= TAG_NAME.Length - 1; i++)
    {
        if (!TAG_NAME[i].Contains("/"))
        {
            writer.WriteStartElement(TAG_NAME[i]);
            if(TAG_VALUE[i] != null) writer.WriteValue(TAG_VALUE[i]);
        }

        if(IS_CONTAINER[i] == 0 || TAG_NAME.Contains("/")) writer.WriteEndElement();
    }

    writer.WriteEndDocument();
}

Note that this algorithm assumes that the DB information is always right and thus does not need to keep track of opened nodes (whenever a closing tag appears a node has to be closed because it is certainly opened). In case of not wanting to trust the correctness of the DB information blindly, you would have to keep track of opened tags.

1
Darshan On

XmlWriter class

var writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;

XmlWriter writer = XmlWriter.Create("d:\\MyFirstXmlFile.xml", writerSettings);

writer.WriteStartDocument();
writer.WriteStartElement("People");

writer.WriteStartElement("Person");
writer.WriteElementString("Name", "Zain Shaikh");
writer.WriteElementString("JobDescription", "Software Engineer");
writer.WriteElementString("Facebook", "http://www.facebook.com/zainshaikh");
writer.WriteEndElement();

writer.WriteEndElement();
writer.WriteEndDocument();

writer.Flush();