2

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();
}
droidlooms
  • 35
  • 5

1 Answers1

1

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)

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • i am trying to merge fragments together. Each fragment has got their own prefix. I am trying to bring in the constant prefix so that i can define the namespace at document level rather doing it for every element in all the fragments. – droidlooms Mar 21 '13 at 22:42
  • @droidlooms: You could still put the namespace at the root and it should work for the lower values. If the namespace is already defined at the lower level you could remove it, although doing that automatically may be difficult. – Guvante Mar 21 '13 at 22:45
  • Any idea how can we merge these two, – droidlooms Mar 21 '13 at 22:55
  • Why does it matter to you if every fragment has a different prefix, as long as the namespaces are the same? – John Saunders Mar 21 '13 at 22:58
  • redundancy, i have got the file(post merge) with size 1.4GB – droidlooms Mar 21 '13 at 22:59
  • 1
    It would be interesting to see how much the file size changes once you 'fix" this. It would also be interesting to see how much time is spent in "fixing" this. – John Saunders Mar 22 '13 at 00:31
  • than you guys for response. Above code works to remove the attributes well. But that didnt quite take me to the shore, i still want to retain the values at element level. see this, to be merged as – droidlooms Mar 22 '13 at 16:57
  • @droidlooms: Please don't attempt to put XML into comments, it is impossible to read. Update the question if you want to expand. Make sure you include what you have done so far as well. – Guvante Mar 22 '13 at 17:01
  • Thanks for providing some insights – droidlooms Mar 22 '13 at 21:30