XMLWriter: WriteStartElement with a tag name and string to indicate tag name

10,485

Solution 1

The question seems to be about the <entry> tags; that is basically a series of 5 blocks similar to:

xw.WriteStartElement("entry");
xw.WriteAttributeString("key", "RecordTotal");
xw.WriteString("10");
xw.WriteEndElement();

However, you might also want to look at XmlSerializer - would probably make this a lot easier:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

static class Program {
    static void Main() {
        var order = new Order {
            ClientId = 1001,
            Id = 58239346,
            Config = new OrderConfig {
                Id = 19,
                Properties = {
                    new OrderProperty { Key = "RecordTotal", Value = "10"},
                    new OrderProperty { Key = "InputFileName", Value = "name"},
                    new OrderProperty { Key = "ConfigName", Value = "COMMON_"},
                    new OrderProperty { Key = "DeliveryDate", Value = "15-FEBRUARY-2013"},
                    new OrderProperty { Key = "Qualifier", Value = "name"}
                }
            }
        };
        var ser = new XmlSerializer(typeof(Order));
        ser.Serialize(Console.Out, order);
    }
}
[XmlRoot("order")]
public class Order {
    [XmlElement("clientID", Order = 0)]
    public int ClientId { get; set; }    
    [XmlElement("config", Order = 1)]
    public OrderConfig Config { get; set; }    
    [XmlElement("orderID", Order = 2)]
    public int Id { get; set; }
}

public class OrderConfig {
    [XmlElement("id", Order = 2)]
    public int Id { get; set; }    
    private readonly List<OrderProperty> properties = new List<OrderProperty>();
    [XmlArray("properties", Order = 1), XmlArrayItem("entry")]
    public List<OrderProperty> Properties { get { return properties; } }
}

public class OrderProperty {
    [XmlAttribute("key")]
    public string Key {get;set;}
    [XmlText]
    public string Value {get;set;}
}

Solution 2

I'd be tempted to use Linq-to-XML for this:

using System;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            XElement root = 
                new XElement("order",
                    new XElement("clientId", 1001),
                    new XElement("config",
                        new XElement("properties",
                            new XElement("entry", new XAttribute("key", "RecordTotal"), 10),
                            new XElement("entry", new XAttribute("key", "InputFileName"), "name"),
                            new XElement("entry", new XAttribute("key", "ConfigName"), "COMMON"),
                            new XElement("entry", new XAttribute("key", "DeliveryDate"), "15-FEBRUARY-2013"),
                            new XElement("entry", new XAttribute("key", "Qualifier"), "name")),
                        new XElement("id", 19)),
                    new XElement("orderID", 58239346)
            );

            Console.WriteLine(root);
        }
    }
}

By way of comparison, if you wanted multiple property elements so the XML looked like this:

<order>
  <clientId>1001</clientId>
  <config>
    <properties>
      <property>
        <entry key="RecordTotal">10</entry>
        <entry key="InputFileName">name</entry>
        <entry key="ConfigName">COMMON</entry>
        <entry key="DeliveryDate">15-FEBRUARY-2013</entry>
        <entry key="Qualifier">name</entry>
      </property>
      <property>
        <entry key="RecordTotal">15</entry>
        <entry key="InputFileName">othername</entry>
        <entry key="ConfigName">UNCOMMON</entry>
        <entry key="DeliveryDate">23-FEBRUARY-2013</entry>
        <entry key="Qualifier">qname</entry>
      </property>
    </properties>
    <id>19</id>
  </config>
  <orderID>58239346</orderID>
</order>

your code could look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            XElement root = 
                new XElement("order",
                    new XElement("clientId", 1001),
                    new XElement("config",
                        new XElement("properties",
                            createEntries(getEntries())),
                        new XElement("id", 19)),
                    new XElement("orderID", 58239346)
            );

            Console.WriteLine(root);
        }

        static IEnumerable<Entry> getEntries()
        {
            yield return new Entry
            {
                RecordTotal   = 10,
                InputFileName = "name",
                ConfigName    = "COMMON",
                DeliveryDate  = "15-FEBRUARY-2013",
                Qualifier     = "name"
            };

            yield return new Entry
            {
                RecordTotal   = 15,
                InputFileName = "othername",
                ConfigName    = "UNCOMMON",
                DeliveryDate  = "23-FEBRUARY-2013",
                Qualifier     = "qname"
            };
        }

        static IEnumerable<XElement> createEntries(IEnumerable<Entry> entries)
        {
            return from entry in entries
                   select new XElement(
                       "property",
                       new XElement("entry", new XAttribute("key", "RecordTotal"),   entry.RecordTotal),
                       new XElement("entry", new XAttribute("key", "InputFileName"), entry.InputFileName),
                       new XElement("entry", new XAttribute("key", "ConfigName"),    entry.ConfigName),
                       new XElement("entry", new XAttribute("key", "DeliveryDate"),  entry.DeliveryDate),
                       new XElement("entry", new XAttribute("key", "Qualifier"),     entry.Qualifier));
        }
    }

    sealed class Entry
    {
        public int RecordTotal;
        public string InputFileName;
        public string ConfigName;
        public string DeliveryDate;
        public string Qualifier;
    }
}

Solution 3

Try this for each entry:

xmlWriter.WriteStartElement("entry");
xmlWriter.WriteAttributeString("key", "RecordTotal");
xmlWriter.WriteValue(10);
xmlWriter.WriteEndElement();
Share:
10,485
king jia
Author by

king jia

Updated on June 05, 2022

Comments

  • king jia
    king jia almost 2 years

    I have same tag names and different strings to different the tag name.

    here is the XML.

    <order>
      <ID>1001</ID> 
      <config>
        <properties>
          <entry key="Total">10</entry> 
          <entry key="Name">name</entry> 
          <entry key="Config">COMMON</entry> 
          <entry key="Delivery">15-FEBRUARY-2013</entry> 
          <entry key="Setting">name</entry> 
        </properties>
        <id>19</id> 
      </config>
      <aID>58239346</aID> 
    </order>
    

    here is my current code:

    public String cards(string id)
        {
            StringWriter str = new StringWriter();
            XmlTextWriter xmlWriter = new XmlTextWriter(str);
            xmlWriter.Formatting = Formatting.Indented;
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("order");
            xmlWriter.WriteElementString("ID", "1001");
            xmlWriter.WriteStartElement("config");
            xmlWriter.WriteStartElement("properties");
            /*
             * Create <entry key> at here 
             * 
             * 
             * 
             *
             */
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();
            xmlWriter.WriteElementString("ClientID", id);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Flush();
            xmlWriter.Close();
            return str.ToString();
        }
    

    How to write the entry tag for XMLWriter??? I have no idea how to write it.

  • Marc Gravell
    Marc Gravell about 11 years
    @kingjia I added a full XmlSerializer example, FYI
  • Marc Gravell
    Marc Gravell about 11 years
    what is your XML_HEADER_FILTER there trying to do? if that is to remove redundant namespace declarations, you can just ask it to not include them...
  • Sean
    Sean about 11 years
    @MarcGravell I have removed the XML_HEADER_FILTER line of code - this still builds without an issue. I had kept this in from a code snippet of my own, apologies.
  • Marc Gravell
    Marc Gravell about 11 years
    but for your info - if it is to remove the xmlns entries, you can instruct XmlSerializer to omit them; if you look at my example on this question, but change the last line to: var ns = new XmlSerializerNamespaces(); ns.Add("", ""); ser.Serialize(Console.Out, order, ns); - then no xmlns entries are output
  • Sean
    Sean about 11 years
    @MarcGravell Thank you for this, Marc - much appreciated.