Using XMLWriter to create a custom header in C# - c#

I'm fairly new to XML and very new to using the XMLWriter object. I've been successful in using it to write a "Well Formed" XML file, but after many failed attempts to create the needed header, below, I've decided to come here for some insight.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE IDMS-XML SYSTEM "http://eclipseinc.com/dtd/IDMS-XML.dtd">
<IDMS-XML>
....
Here's the beginning of my code (very standard):
using (XmlWriter xmlWriter = XmlWriter.Create("SendXML.xml"))
{
xmlWriter.WriteStartDocument();
....
I've tried using things like xmlWriter.WriteString() to force it in, but that has been unsuccessful for me. Thanks for any and all insight.

You need to be more clear what the “it” you are trying to “force in” is. Do you mean the <!DOCTYPE ...? That is a doctype declaration, and XmlWriter has a built-in method for adding one. To create a SYSTEM doctype try:
xmlWriter.WriteDocType("IDMS-XML", null, "http://eclipseinc.com/dtd/IDMS-XML.dtd", null);
If that is not what you mean you must be more explicit.

In order to write to the xml file you need to create the XmlTextWriter then create a node to make a header. Hope this helps you out a bit.
XmlTextWriter writer = new XmlTextWriter("filename",System.Text.Encoding.UTF8); writer.WriteStartDocument(True)
writer.WriteStartElement("Start Element Name")
createNode("NodeName", writer)
writer.WriteEndElement()
writer.WriteEndDocument()
writer.Close()
public void createnode(String nodename, XmlTextWriter writer)
{
writer.WriteStartElement("Name Here")
writer.WriteString(nodename)
writer.WriteEndElement()
}

Related

How to create an XDocument given an XmlWriter?

We have a method that writes XML into an XmlWriter, we use this to generate a stream of XML directly without having to go via some form of DOM. However there are occasions where we do want to create a DOM. One approach would be to always build a DOM and to stream from that (to cover both requirements), but we like the performance of writing XML directly. Therefore we want to build a DOM from an XmlWriter.
See How to create a XmlDocument using XmlWriter in .NET? for an example of how to create an XmlDocument from an XmlWriter, albeit using a slightly off-piste code pattern. Are there similar options if I want an XDocument (or XElement subtree) instead?
Have a look at the XContainer.CreateWriter Method:
XContainer.CreateWriter Method
Creates an XmlWriter that can be used to add nodes to the XContainer.
Both XDocument and XElement are XContainers.
Example:
XDocument doc = new XDocument();
using (XmlWriter writer = doc.CreateWriter())
{
// Do this directly
writer.WriteStartDocument();
writer.WriteStartElement("root");
writer.WriteElementString("foo", "bar");
writer.WriteEndElement();
writer.WriteEndDocument();
// or anything else you want to with writer, like calling functions etc.
}

How to transform XMLDocument using XSLT in C# 2.0

I am using C# 2.0 and I have got below code:
XmlDocument doc = new XmlDocument();
doc.LoadXml(GetListOfPagesInStructureGroup(m_Page.Id));
In above I am loading my XMLDocument with method which returns as string, now after some processing on above xmldocument I want to apply XSLT on the above XMLDocument to render my desired result according to XSLT and finally my function will return whole rendered XML as string
Please suggest!!
Please suggest on below solution:
XslCompiledTransform xslTransform = new XslCompiledTransform();
StringWriter writer = new StringWriter();
xslTransform.Load("xslt/RenderDestinationTabXML.xslt");
xslTransform.Transform(doc.CreateNavigator(),null, writer);
return writer.ToString();
Thanks!!
Try the XslCompiledTransform class.
There are lots of examples on the web of transforming an XML file to a different format using an XSLT file, like the following:
XslTransform myXslTransform = new XslTransform();
XsltSettings myXsltSettings = new XsltSettings();
myXsltSettings.EnableDocumentFunction = true;
myXslTransform.Load("transform.xsl");
myXslTransform.Transform("input.xml", "output.xml");
However this is only a partial answer, I would like to be able to get the XML input data from a web form and use that as the input data instead of an '.xml' file, but have not found any concrete examples, also using Visual Studio I can see the different constructors and methods that are available and I am not seeing one that accepts xml data in a string format, so it would be very helpful if someone could provide an example of that.
Re " I want my same XMlDocument updated " - it doesn't work like that; the output is separate to the input. If that is important, just use a StringWriter or MemoryStream as the destination, then reload the XmlDocument from the generated output.
Consider in particular: the output from an xslt transformation does not have to be xml, and also: the xslt is most likely using the node tree during the operation; changing the structure in-place would make that very hard.

Remove whitespace in self closing tags when writing xml document

When writing out an xml document I need to write all self closing tags without any whitespace, for example:
<foo/>
instead of:
<foo />
The reason for this is that a vendor system that I'm interfacing with throws a fit otherwise. In an ideal world the vendor would fix their system, but I don't bet on that happening any time soon. What's the best way to get an XmlWriter to output the self closing tags without the space?
My current scheme is to do something like:
return xml.Replace(" />", "/>");
Obviously this is far from ideal. Is it possible to subclass the XmlWriter for that one operation? Is there a setting as part of the XmlWriterSettings that I've overlooked?
I think that there is no such option to avoid that one space in self-closing tag. According to MSDN, XmlTextWriter:
When writing an empty element, an
additional space is added between tag
name and the closing tag, for example
. This provides compatibility
with older browsers.
Hopefully you could write <elementName></elementName> syntax instead of unwanted <elementName />, to do that use XmlWriter.WriteFullEndElement method, e.g.:
using System.Xml;
..
static void Main(string[] args)
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.IndentChars = ("\t");
xmlWriterSettings.OmitXmlDeclaration = true;
XmlWriter writer = XmlWriter.Create("example.xml", xmlWriterSettings);
writer.WriteStartElement("root");
writer.WriteStartElement("element1");
writer.WriteEndElement();
writer.WriteStartElement("element2");
writer.WriteFullEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
}
produces following XML document:
<root>
<element1 />
<element2></element2>
</root>
Use a different serializer, for example the Saxon serializer, which also runs on .NET. It so happens that the Saxon serializer does what you want.
It's horrible, of course, to choose products based on accidental behaviour that no self-respecting system would require, but you have to accept reality - if you want to trade with idiots, you have to behave like an idiot.
Try this:
x.WriteStartElement("my-tag");
//Value of your tag is null
If (<"my-tag"> == "")
{
x.WriteWhitespace("");
}else
x.WriteString(my-tag);
x.WriteEndElement();

Getting "" at the beginning of my XML File after save() [duplicate]

This question already has answers here:
How can I remove the BOM from XmlTextWriter using C#?
(2 answers)
Closed 7 years ago.
I'm opening an existing XML file with C#, and I replace some nodes in there. All works fine. Just after I save it, I get the following characters at the beginning of the file:
 (EF BB BF in HEX)
The whole first line:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
The rest of the file looks like a normal XML file.
The simplified code is here:
XmlDocument doc = new XmlDocument();
doc.Load(xmlSourceFile);
XmlNode translation = doc.SelectSingleNode("//trans-unit[#id='127']");
translation.InnerText = "testing";
doc.Save(xmlTranslatedFile);
I'm using a C# Windows Forms application with .NET 4.0.
Any ideas? Why would it do that? Can we disable that somehow? It's for Adobe InCopy, and it does not open it like this.
UPDATE:
Alternative Solution:
Saving it with the XmlTextWriter works too:
XmlTextWriter writer = new XmlTextWriter(inCopyFilename, null);
doc.Save(writer);
It is the UTF-8 BOM, which is actually discouraged by the Unicode standard:
http://www.unicode.org/versions/Unicode5.0.0/ch02.pdf
Use of a BOM is neither required nor
recommended for UTF-8, but may be
encountered in contexts where UTF-8
data is converted from other encoding
forms that use a BOM or where the BOM
is used as a UTF-8 signature
You may disable it using:
var sw = new IO.StreamWriter(path, new System.Text.UTF8Encoding(false));
doc.Save(sw);
sw.Close();
It's a UTF-8 Byte Order Mark (BOM) and is to be expected.
You can try to change the encoding of the XmlDocument. Below is the example copied from MSDN
using System; using System.IO; using System.Xml;
public class Sample {
public static void Main() {
// Create and load the XML document.
XmlDocument doc = new XmlDocument();
string xmlString = "<book><title>Oberon's Legacy</title></book>";
doc.Load(new StringReader(xmlString));
// Create an XML declaration.
XmlDeclaration xmldecl;
xmldecl = doc.CreateXmlDeclaration("1.0",null,null);
xmldecl.Encoding="UTF-16";
xmldecl.Standalone="yes";
// Add the new node to the document.
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmldecl, root);
// Display the modified XML document
Console.WriteLine(doc.OuterXml);
}
}
As everybody else mentioned, it's Unicode issue.
I advise you to try LINQ To XML. Although not really related, I mention it as it's super easy compared to old ways and, more importantly, I assume it might have automatic resolutions to issues like these without extra coding from you.

Proper name space management in .NET XmlWriter

I use .NET XML technologies quite extensively on my work. One of the things the I like very much is the XSLT engine, more precisely the extensibility of it. However there one little piece which keeps being a source of annoyance. Nothing major or something we can't live with but it is preventing us from producing the beautiful XML we would like to produce.
One of the things we do is transform nodes inline and importing nodes from one XML document to another.
Sadly , when you save nodes to an XmlTextWriter (actually whatever XmlWriter.Create(Stream) returns), the namespace definitions get all thrown in there, regardless of it is necessary (previously defined) or not. You get kind of the following xml:
<root xmlns:abx="http://bladibla">
<abx:child id="A">
<grandchild id="B">
<abx:grandgrandchild xmlns:abx="http://bladibla" />
</grandchild>
</abx:child>
</root>
Does anyone have a suggestion as to how to convince .NET to be efficient about its namespace definitions?
PS. As an added bonus I would like to override the default namespace, changing it as I write a node.
Use this code:
using (var writer = XmlWriter.Create("file.xml"))
{
const string Ns = "http://bladibla";
const string Prefix = "abx";
writer.WriteStartDocument();
writer.WriteStartElement("root");
// set root namespace
writer.WriteAttributeString("xmlns", Prefix, null, Ns);
writer.WriteStartElement(Prefix, "child", Ns);
writer.WriteAttributeString("id", "A");
writer.WriteStartElement("grandchild");
writer.WriteAttributeString("id", "B");
writer.WriteElementString(Prefix, "grandgrandchild", Ns, null);
// grandchild
writer.WriteEndElement();
// child
writer.WriteEndElement();
// root
writer.WriteEndElement();
writer.WriteEndDocument();
}
This code produced desired output:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:abx="http://bladibla">
<abx:child id="A">
<grandchild id="B">
<abx:grandgrandchild />
</grandchild>
</abx:child>
</root>
Did you try this?
Dim settings = New XmlWriterSettings With {.Indent = True,
.NamespaceHandling = NamespaceHandling.OmitDuplicates,
.OmitXmlDeclaration = True}
Dim s As New MemoryStream
Using writer = XmlWriter.Create(s, settings)
...
End Using
Interesting is the 'NamespaceHandling.OmitDuplicates'
I'm not sure this is what you're looking for, but you can use this kind of code when you start writing to the Xml stream:
myWriter.WriteAttributeString("xmlns", "abx", null, "http://bladibla");
The XmlWriter should remember it and not rewrite it anymore. It may not be 100% bulletproof, but it works most of the time.

Categories

Resources