I'm currently using Syntax Highlighter to show a XML or SOAP messages on a page. That works fine for messages that are already formatted correctly (line breaks, indents, etc). But if I had a XML string like:
string xml = "<doc><object><first>Joe</first><last>Smith</last></object></doc>";
I would write the string to the page and the javascript highlighter would correctly syntax highlight the string, but it would be all on a single line.
Is there a C# string formatter or some syntax highlighting library that has a "smart" indent feature that would insert line breaks, indents, etc... ?
Since this is a string, adding line breaks and indents would be changing the actual value of variable xml, which is not what you want your code formatter to do!
Note that you can format the XML in C# before writing to the page, like this:
using System;
using System.IO;
using System.Text;
using System.Xml;
namespace XmlIndent
{
class Program
{
static void Main(string[] args)
{
string xml = "<doc><object><first>Joe</first><last>Smith</last></object></doc>";
var xd = new XmlDocument();
xd.LoadXml(xml);
Console.WriteLine(FormatXml(xd));
Console.ReadKey();
}
static string FormatXml(XmlDocument doc)
{
var sb = new StringBuilder();
var sw = new StringWriter(sb);
XmlTextWriter xtw = null;
using(xtw = new XmlTextWriter(sw) { Formatting = Formatting.Indented })
{
doc.WriteTo(xtw);
}
return sb.ToString();
}
}
}
Related
Problem: I need to check whether an incoming document, inside an XML element, is XML or Edifact formatted. Depending on what format the document has, it needs to be processed accordingly.
Current solution: An XDocument instance is created from the incoming message. The incoming message is always XML.
var originalStream = pInMsg.BodyPart.GetOriginalDataStream();
XDocument xDoc;
using (XmlReader reader = XmlReader.Create(originalStream))
{
reader.MoveToContent();
xDoc = XDocument.Load(reader);
}
After this the document is extracted from the XML element "msgbody". Currently it assumes this to be XML formatted, which throws an error when the document is Edifact formatted. The code below extracts it, and the creates a new XDocument, which is sent to the MessageBox.
string extractedDocument = xDoc.Root.Element("msgbody").Value;
extractedDocument = HttpUtility.HtmlDecode(extractedDocument);
XDocument outputXml = XDocument.Parse(extractedDocument);
Example message from biztalk:
<NewTable>
<conversationID>2ff845e7-30a4-482e-98d6-8c3249c5dea1</conversationID>
<hostUTC>2018-12-17T12:17:04.107Z</hostUTC>
<msgType>INVOIC</msgType>
<msgid>721254</msgid>
<icref>36655</icref>
<msgFormat_org>EDIFACTBauhaus</msgFormat_org>
<msgFormat>EDI</msgFormat>
<msgbody>"Edifact or XML document"</msgbody>
<fromID>GLN:5790034516518</fromID>
<toID>GLN:5790000451485</toID>
</NewTable>
Question: How can I create a check for the document inside the msgbody tag, to determine whether it is XML or Edifact formatted, before processing it?
I like using a dictionary to get all the properties using xml linq. See code below. If you are getting string response the nuse instead of the Load(filename) method use Parse(string).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication93
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, string> dict = doc.Descendants("NewTable").Elements()
.GroupBy(x => x.Name.LocalName, y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
I've been using this function to read XML from a string and apply an XSLT style sheets, it has been working very well for small portions of XML:
private static string TransformXML(String XML, String XSLT)
{
string output = String.Empty;
using (StringReader srt = new StringReader(XSLT))
{
using (StringReader sri = new StringReader(XML))
{
using (XmlReader xrt = XmlReader.Create(srt))
using (XmlReader xri = XmlReader.Create(sri))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xrt);
using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings)) // use OutputSettings of xsl, so it can be output as HTML
{
xslt.Transform(xri, xwo);
output = sw.ToString();
}
}
}
}
return output;
}
However, with large portions of XML, I'm getting errors, even though I know it is correctly formatted.
Here is an example error: Unexpected end of file while parsing Name has occurred. Line 1, position 30001.
I'm guessing there is a limit on the buffering, but I can't quite work it out - the code is within an SSIS package and different script tasks produce and translate the XML.
I appreciate any help!
I have a object which has a string property that has a value with double quotes in it. I need to serialize this object and then use that XML. I wont be deserializing this xml.
I am having trouble getting the right content in the XML file. Let me explain with a code sample:
[Serializable]
public class Test {
[XmlElement]
public string obj { get; set; }
}
class Program {
static void Main(string[] args) {
var st ="Priority == \"1\"";
Test test = new Test();
test.obj = st;
//Serialize this object
XmlSerializer xsSubmit = new XmlSerializer(typeof(Test));
StringWriter sww = new StringWriter();
XmlWriter writer = XmlWriter.Create(sww, new XmlWriterSettings {
OmitXmlDeclaration = true
});
var ns = new XmlSerializerNamespaces();//just to make things simpler here
ns.Add(string.Empty, string.Empty);
xsSubmit.Serialize(writer, test, ns);
//My XML
var xml = sww.ToString();
}
}
I need my xml to be:
<Test><obj>Priority=="1"</obj></Test>
I now get:
<Test><obj>Priority==\"1\"</obj></Test>
I even tried to encode the string into HTML using var html = HttpUtility.HtmlEncode(st);
In this case, the varible html is in the right format however on serializing I get:
<Test><obj>Priority=="1"</obj></Test>
Need some help please.
There was no issue with the code.
I actually get<Test><obj>Priority=="1"</obj></Test> and this is fine. The mistake I was making was that I was reading the value on the debugger. When I write it somewhere, the content was in the correct format.
The " didnt get converted to " because double quotes are as such accepted in an XML document. I can work with that in this case!
I am trying to change the default indentation of XDocument from 2 to 3, but I'm not quite sure how to proceed. How can this be done?
I'm familiar with XmlTextWriter and have used code as such:
using System.Xml;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
string destinationFile = "C:\myPath\results.xml";
XmlTextWriter writer = new XmlTextWriter(destinationFile, null);
writer.Indentation = 3;
writer.WriteStartDocument();
// Add elements, etc
writer.WriteEndDocument();
writer.Close();
}
}
}
For another project I used XDocument because it works better for my implementation similar to this:
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Xml;
using System.Text;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
// Source file has indentation of 3
string sourceFile = #"C:\myPath\source.xml";
string destinationFile = #"C:\myPath\results.xml";
List<XElement> devices = new List<XElement>();
XDocument template = XDocument.Load(sourceFile);
// Add elements, etc
template.Save(destinationFile);
}
}
}
As #John Saunders and #sa_ddam213 noted, new XmlWriter is deprecated so I dug a little deeper and learned how to change indentation using XmlWriterSettings. The using statement idea I got from #sa_ddam213.
I replaced template.Save(destinationFile); with the following:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = " "; // Indent 3 Spaces
using (XmlWriter writer = XmlTextWriter.Create(destinationFile, settings))
{
template.Save(writer);
}
This gave me the 3 space indentation that I needed. If more spaces are needed, just add them to IndentChars or "\t" can be used for tab.
I've generated a HTML file and the top html declaration looks like this:
<html xml:lang="de-CH" lang="de-CH" xmlns="http://www.w3.org/1999/xhtml">
And then I try to convert it into a different format with this .Net 4 code:
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Ignore;
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load("Html_to_Sql.xslt");
fsHtmlXml = new FileStream(file.Name, FileMode.Create);
html = XmlReader.Create(file.FullName, settings);
proc.Transform(html, null, fsHtmlXml);
Unfortunately nothing happens as long as I have the xml, lang and xmlns attributes in the HTML.
Why is that?
Your XSLT will need to refer to elements in the http://www.w3.org/1999/xhtml namespace. You haven't posted your XSLT code yet, the the problem most likely lies in that file.
Will this work via XML and XPath
using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
public class TransformXML
{
//This will transform xml document using xslt and produce result xml document
//and display it
public static void Main(string[] args)
{
try
{
XPathDocument myXPathDocument = new XPathDocument(sourceDoc);
XslTransform myXslTransform = new XslTransform();
XmlTextWriter writer = new XmlTextWriter(resultDoc, null);
myXslTransform.Load(xsltDoc);
myXslTransform.Transform(myXPathDocument, null, writer);
writer.Close();
StreamReader stream = new StreamReader (resultDoc);
Console.Write("**This is result document**\n\n");
Console.Write(stream.ReadToEnd());
}
catch (Exception e)
{
Console.WriteLine ("Exception: {0}", e.ToString());
}
}
}
The xmlns attribute specifies the namespace of the XML document. This works in much the same way as namespaces within C#, where two classes with the same name but different namespaces are considered to be completely different classes. Changing the XML namespaces means that your XSLT templates / XPath will not match.