I have to generate specific XML data from code.
The XML needs to look like this
<this:declarationIdentifier xmlns:this="demo.org.uk/demo/DeclarationGbIdentifier"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="demo.org.uk/demo/DeclarationGbIdentifier DeclarationGbIdentifier.xsd"
xmlns:nsIdentity="demo.org.uk/demo/DeclarationGbIdentityType">
<this:declarationIdentity>
<nsIdentity:declarationUcr>Hello World</nsIdentity:declarationUcr>
</this:declarationIdentity>
</this:declarationIdentifier>
I have dabbled with XmlSerializer and XDocument but cant get the output to match this exactly
Please help.
I believe this will produce your desired output. There possibly is a simpler way this is just off the cuff to get you started. With the prefixes that you are requiring I would look up XmlDocument and adding namespaces to it to have a better understanding of what the code below is doing. Also what I would do is attempt to acquire the XSD schema file and use the XSD.exe to build a .cs file and then you can move forward with the XmlSerializer. If you move forward with the code below i highly suggest moving off your namespaceuri's into some soft of settings file so you can easily modify them in the event they change.
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("this", "declarationIdentifier", "demo.org.uk/demo/DeclarationGbIdentifier");
root.SetAttribute("xmlns:this", "demo.org.uk/demo/DeclarationGbIdentifier");
root.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
//Just setting an Attribute of xsi:schemaLocation it would always drop the xsi prefix in the xml so this is different to accomodate that
XmlAttribute schemaAtt = doc.CreateAttribute("xsi", "schemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
schemaAtt.Value = "demo.org.uk/demo/DeclarationGbIdentifier DeclarationGbIdentifier.xsd";
root.Attributes.Append(schemaAtt);
root.SetAttribute("xmlns:nsIdentity", "demo.org.uk/demo/DeclarationGbIdentityType");
doc.AppendChild(root);
XmlElement declarationIdentity = doc.CreateElement("this", "declarationIdentity", "demo.org.uk/demo/DeclarationGbIdentifier");
XmlElement declarationUcr = doc.CreateElement("nsIdentity","declarationUcr","demo.org.uk/demo/DeclarationGbIdentityType");
declarationUcr.InnerText = "Hello World";
declarationIdentity.AppendChild(declarationUcr);
doc.DocumentElement.AppendChild(declarationIdentity);
To output this as a string or dump it off to a file you can use the following operations, I output to a file as well as output to the console in my test app.
using (var stringWriter = new StringWriter())
using (StreamWriter writer = new StreamWriter(#"C:\<Path to File>\testing.xml"))
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
{
doc.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
writer.Write(stringWriter.GetStringBuilder().ToString());
Console.WriteLine(stringWriter.GetStringBuilder().ToString());
}
Related
I am seeking a help regarding file saving of XML file using XDocument (NOT XMLDocument).
So I have a xml file that does not have indentation (in fact it is 1 line). When I read this to XDocument using XDocument.Parse (after reading and storing string using StreamReader), the resulting XDocument is indented.
Alright, I thought it will be fine as long as if I can save it back to the file without indentation. However, even though I have
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.NewLineOnAttributes = false;
writerSettings.NewLineHandling = NewLineHandling.None;
writerSettings.Indent = false;
and pass that in when I create XmlWriter
using (var writer = XmlWriter.Create(u.ToFileSystemPath(), settings))
{
xd.Save(writer);
}
The resulting XML file still has indentation. When I am debugging on Visual studio, I noticed that the writer is a class XmlWellFormedWriter. Does this have something to do with my result? Any help would be appreciated.
Thank you.
SaveOptions are available on Save() as well as ToString().
string xmlstring =
#"<Top>
<First>1</First>
<Second>Dude</Second>
<Third>Now</Third>
</Top>";
XDocument doc = XDocument.Parse(xmlstring);
doc.Save(#"C:\temp\noIndet.xml", SaveOptions.DisableFormatting);
// string noIndent = doc.ToString(SaveOptions.DisableFormatting);
Output:
I'm trying to create an XML with multiple root elements. I can't change that because that is the way I'm supposed to send the XML to the server. This is the error I get when I try to run the code:
System.InvalidOperationException: This operation would create an incorrectly structured document.
Is there a way to overwrite this error and have it so that it ignores this?
Alright so let me explain this better:
Here is what I have
XmlDocument doc = new XmlDocument();
doc.LoadXml(_application_data);
Now that creates the XML document and I can add a fake root element to it so that it works. However, I need to get rid of that and convert it into a DocumentElement object.
How would I go about doing that?
Specify Fragment when creating XmlWriter as shown here
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.CloseOutput = false;
// Create the XmlWriter object and write some content.
MemoryStream strm = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(strm, settings))
{
writer.WriteElementString("orderID", "1-456-ab");
writer.WriteElementString("orderID", "2-36-00a");
writer.Flush();
}
If it has multiple root elements, it's not XML. If it resembles XML in other ways, you could place everything under a root element, then when you send the string to the server, you just combine the serialized child elements of this root element, or as #Austin points out, use an inner XML method if available.
just create an XML with single root then get it's content as XML text.
you are talking about XML fragment anyways, since good xml has only one root.
this is sample to help you started:
var xml = new XmlDocument();
var root = xml.CreateElement("root");
root.AppendChild(xml.CreateElement("a"));
root.AppendChild(xml.CreateElement("b"));
Console.WriteLine(root.InnerXml); // outputs "<a /><b />"
I'm sorry if this is an obvious question, but I'm getting abit frustrated trying to find an answer.
Can I perform an XSL transform on a loaded XmlDocument in place? That is, without having to create a writer to the document?
I ask because I have an XmlDocument binding inside a WPF app that I want to sort. The sorts can get a little complicated so XSL seemed a good fit. Here's the code that I'm stuck at:
XmlDataProvider xmlDP = (XmlDataProvider)this.Resources["ItemDB"];
string xsltPath = System.Configuration.ConfigurationManager.AppSettings["XSLDirextory"];
string path = xsltPath + "SortItemName.xslt";
if (System.IO.File.Exists(path))
{
XslCompiledTransform compTrans = new XslCompiledTransform();
compTrans.Load(path);
//compTrans.Transform(xmlDP.Document, new XsltArgumentList(), xmlDP.Document.XmlResolver);
}
After loading the transform, I'd like to just be able to compTrans(xmlDP.Document); or something that has the same effect. (to be clear, xmlDP.Document is an XmlDocument ) so that the XmlDocument has the result of the transform.
What's the best way to accomplish this?
The closest you can do is create a new XmlDocument with e.g.
XmlDocument result = new XmlDocument();
using (XmlWriter xw = result.CreateNavigator().AppendChild())
{
compTrans.Transform(xmlDP.Document, null, xw);
xw.Close();
}
and then assign that to your property:
xmlDP.Document = result;
Of course that requires that xmlDP.Document can be set.
XSLT always creates a new document to hold the transformation result, it never modifies the input document.
Let's say I have a System.Xml.XmlDocument whose InnerXml is:
<comedians><act id="1" type="single" name="Harold Lloyd"/><act id="2" type="duo" name="Laurel and Hardy"><member>Stan Laurel</member><member>Oliver Hardy</member></act></comedians>
I'd like to format it thusly, with newlines and whitespace added:
<comedians>
<act id="1" type="single" name="Harold Lloyd"/>
<act id="2" type="duo" name="Laurel and Hardy">
<member>Stan Laurel</member>
<member>Oliver Hardy</member>
</act>
</comedians>
I looked in the XmlDocument class for some prettifying method, but couldn't find one.
Basically you can use XmlDocument.Save(Stream) and pass any Stream as target to receive the xml content. Including a "memory-only" StringWriter as below:
string xml = "<myXML>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
using(StringWriter sw = new StringWriter())
{
doc.Save(sw);
Console.Write(sw.GetStringBuilder().ToString());
}
Update: using block
Jon Galloway posted an answer and deleted it, but it was actually the best option for me. It went somewhat like this:
StringBuilder Prettify(XmlDocument xdoc)
{
StringBuilder myBuf = new StringBuilder();
XmlTextWriter myWriter = new XmlTextWriter(new StringWriter(myBuf));
myWriter.Formatting = Formatting.Indented;
xdoc.Save(myWriter);
return myBuf;
}
No need to create a XmlWriterSettings object.
Trying to prettify XML is like putting lipstick on a pig :) It still ain't gonna be pretty.
Why are you trying to prettify it? If it is for editing purposes, Visual Studio does a pretty good job of presenting it in readable form. If it is for a user, then they may prefer to just open up in their preferred editor or explorer.
I'm writing a Windows service in C#. I've got an XmlWriter which is contains the output of an XSLT transformation. I need to get the XML into an XMLElement object to pass to a web service.
What is the best way to do this?
You do not need an intermediate string, you can create an XmlWriter that writes directly into an XmlNode:
XmlDocument doc = new XmlDocument();
using (XmlWriter xw = doc.CreateNavigator().AppendChild()) {
// Write to `xw` here.
// Nodes written to `xw` will not appear in the document
// until `xw` is closed/disposed.
}
and pass xw as the output of the transform.
NB. Some parts of the xsl:output will be ignored (e.g. encoding) because the XmlDocument will use its own settings.
Well, an XmlWriter doesn't contain the output; typically, you have a backing object (maybe a StringBuilder or MemoryStream) that is the dumping place. In this case, StringBuilder is probably the most efficient... perhaps something like:
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb))
{
// TODO write to writer via xslt
}
string xml = sb.ToString();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlElement el = doc.DocumentElement;
If you provide a writer, you provide a repository where an output generator is transferring data, thus the replay of Richard is good, you don't really need a string builder to send data from a reader to an XmlDocument!