Update: updated question to address the problem is elements and not atrributes and added my XML output
I have to feed an application some XML encoded strings (I don't use markup languages often and don't have a lot of experience with their nuances).
The format I need to send it is below(out of my control):
<ROOT>
<Unit UnitName="Unit XYZ">
<Scheds Qty="5" ProdId="214" Comments="" />
<Scheds Qty="200" ProdId="125" Comments="Need by 1/23" />
<Scheds Qty="5000" ProdId="3100" Comments="" />
</Unit>
<Unit UnitName="Unit ABC">
<Scheds Qty="5" ProdId="214" Comments="" />
<Scheds Qty="200" ProdId="125" Comments="Need by 1/25" />
<Scheds Qty="5000" ProdId="3100" Comments="" />
</Unit>
</ROOT>
I've tried to write this using XML Writer
but am having issues with the Attribute Scheds
being duplicate.
You can see below I was fiddling with the WriteString
method but I believe I need it to be an attribute.
My code below:
//Top level root element
writer.WriteStartElement("ROOT");
//loop through list and determine the pu desc to create the xml element
foreach (Tuple<int, List<PLYOrder>> t in allOrders)
{
var unit = PUList.Where(x => x.PUId == t.Item1).First().PUDesc.ToString();
//Start each Unit as a new element
writer.WriteStartElement("Unit");
writer.WriteAttributeString("UnitName", unit);
foreach(PLYOrder p in t.Item2)
{
var qty = $"Qty=\"{p.Qty.ToString()}\"";
var prodId = $"ProdId=\"{p.Product.Id.ToString()}\"";
var Comments = $"Comments=\"{p.Comments}\"";
writer.WriteStartElement("Scheds", qty);
writer.WriteEndElement();
writer.WriteStartElement("Scheds", prodId);
writer.WriteEndElement();
writer.WriteStartElement("Scheds", comments);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
writer.WriteEndElement();
Produces the below output in Visual Studio debugger XML view of variable:
-<ROOT>
-<Unit UnitName="XYZ">
<Scheds xmlns="Qty="5""/>
<Scheds xmlns="ProdId="360""/>
<Scheds xmlns="Comments="hhh""/>
<Scheds xmlns="Qty="66""/>
<Scheds xmlns="ProdId="356""/>
<Scheds xmlns="Comments="""/>
</Unit>
-<Unit UnitName="ABC">
<Scheds xmlns="Qty="44""/>
<Scheds xmlns="ProdId="356""/>
<Scheds xmlns="Comments="gg""/>
</Unit>
</ROOT>
It looks like you're using WriteStartElement incorrectly. The second parameter is not an attribute, but a namespace URI. Here's a simple example
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
XmlWriter writer = XmlWriter.Create(Console.Out, settings);
writer.WriteStartElement("ROOT");
writer.WriteStartElement("Unit");
writer.WriteAttributeString("UnitName", "Unit XYZ");
writer.WriteEndElement();
writer.WriteStartElement("Scheds");
writer.WriteAttributeString("Qty", "5");
writer.WriteAttributeString("ProdId", "214");
writer.WriteAttributeString("Comments", "Need by 1/25");
writer.WriteEndElement();
// Write the close tag for the root element.
writer.WriteEndElement();
writer.Close();
This produces the following output:
<ROOT>
<Unit UnitName="Unit XYZ" />
<Scheds Qty="5" ProdId="214" Comments="Need by 1/25" />
</ROOT>
So from your example it would be:
foreach(PLYOrder p in t.Item2)
{
writer.WriteStartElement("Scheds");
writer.WriteAttributeString("Qty", p.Qty.ToString());
writer.WriteAttributeString("ProdId", p.Product.Id.ToString());
writer.WriteAttributeString("Comments", p.Comments);
writer.WriteEndElement();
}