Question

I am trying to generate a piece of xml data using linq to xml.

XNamespace xsins = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
XAttribute xsiniltrue = new XAttribute(xsins+"Exists", "true");
XElement elem = new XElement("CustomerRecord", xsiniltrue);

This generates the prefix for xsins at runtime and they looks bogus.

<Fragment>
    <CustomerRecord p5:Exists="true" xmlns:p5="w3.org/2001/XMLSchema-instance"; /> 
</Fragment> 
<Fragment> 
    <CustomerRecord p3:Exists="false" xmlns:p3="w3.org/2001/XMLSchema-instance"; /> 
</Fragment>

to be merged as

<Fragment xmlns:p5="w3.org/2001/XMLSchema-instance";  >
    <CustomerRecord p5:Exists="true" /> 
    <CustomerRecord p5:Exists="false" /> 
</Fragment>

Also tried to use XMLWriter,

XNamespace xsins = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");

using (var writer = XmlWriter.Create(fullPath, settings))
{
    writer.WriteStartDocument(true);
    writer.WriteStartElement(string.Empty, "Company", "urn:schemas-company");
    //writer.WriteAttributeString(xsins.GetName("xsi"), "http://www.w3.org/2001/XMLSchema-instance");

    writer.WriteStartElement(string.Empty, "Add", "urn:schemas-company");
    foreach (var qx in resultXMLs)
    {
        qx.WriteTo(writer);
    }

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

I have finally cracked it (atleast I hope), below piece solved my issue

using (var writer = XmlWriter.Create(fullPath, settings))
{
    writer.WriteStartDocument(true);
    writer.WriteStartElement(string.Empty, "Company", "urn:schemas-company");
    writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
    writer.WriteStartElement(string.Empty, "Add", "urn:schemas-company");
    foreach (var qx in fragments)
    {
        qx.SetAttributeValue(XNamespace.Xmlns + "xsi", xsins.ToString());
        qx.WriteTo(writer);
    }
    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.WriteEndDocument();
}

No correct solution

OTHER TIPS

You want to control the XML prefix outputted. For reference an MSDN site

Basically you just need to add the xml:xsi to your root node and Linq to XML should take care of the rest.

Note that when you get into really complex examples it tends to fall apart, but it should work in this case.

EDIT:

To remove extraneous attributes, you could simply do it by hand:

foreach(var element in root.Descendents())
{
    foreach (var attribute in element.Attributes())
    {
        if (attribute.Name.Namespace == XNamespace.Xmlns)
           attribute.Remove();
    }
}

Note the above is rough, I don't have an XML project handy.

EDIT:

I am not sure what your input is, but here is an example of hard coding your expected output:

var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
var fragment =
      new XElement("Fragment",
                   new XAttribute(XNamespace.Xmlns + "p5", xsi.ToString()),
                   new XElement("CustomerRecord",
                                new XAttribute(xsi + "Exists", "true")),
                   new XElement("CustomerRecord",
                                new XAttribute(xsi + "Exists", "false")));

I tested this and it outputs identical to what you asked for (well I tested in F#, so sorry if there is a syntax error)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top