How apply xsl transform in C# program without safe file? - c#

I neen apply simple xsl transform and continue work whith result data, but I wan't to save file. This is my code:
XslTransform xsl = new XslTransform();
var writer = new MemoryStream();
var xslDoc = new XPathDocument("107901.xslt");
xsl.Load(#"C:\Users\mak\Documents\Visual Studio 2015\Projects\SpellCheck\SpellCheck\GetAllValues.xslt");
xsl.Transform(xslDoc, null, writer);
writer.Position = 1;
var str = new StreamReader(writer);
var normalize = str.ReadToEnd().Trim('�');
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Save(normalize);
1) Why in variable str appears 2 symbol 65533?
2) Why variable normalize not save how xml file? Goes error 'not able to add it to the content characters than whitespace'
Maybe I doing all wrong and can easier.
Sorry for bad english and sanks for answer :-)

Don't understand question no.1 so I'll skip to question 2. If you care to read the documentation, it is clearly mentioned that the string argument of Save() should contains "The location of the file where you want to save the document". As for populating the XmlDocument instance from XML string, you can use LoadXml() :
.....
.....
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(normalize);
xmlDocument.Save("D:\path\to\your\output.xml");

Related

How to workaround 0x01 invalid character exception. Using Xdocument

Im trying to parse a folder with a bunch of xml files. The xml files contains information about some vehicles. The XML files are autogenerated and i some of them has invalid characters. The thing is that, there are too many files for me to correct them manually. So i wonder how i can bypass the invalid character exception?
This is the invalid line in some of the xml files:
<ECU EcuName="ABS" EcuFamily="BSS" CplNo="" Address="0x0B" ConfigChecksum="0x00000000" Updated="false">
I have tried to use Streamreader without any success. This is my code:
XDocument docs = XDocument.Load(new System.IO.StreamReader((path), Encoding.GetEncoding("utf-8")));
var nameValues =
from fpc in docs.Descendants("FPC")
select new
{
Name = (string)fpc.Attribute("Name"),
Value = (string)fpc.Attribute("Value")
};
If you need to you can load the file with e.g.
XDocument doc;
using (XmlReader xr = XmlReader.Create(path, new XmlReaderSettings() { CheckCharacters = false }))
{
doc = XDocument.Load(xr);
}
// now query document here
That will get by character references like the one you have shown, not by disallowed literal characters however.

passing xml data into a string to be used as a parameter

Having trouble dealing with xml and to properly use it for my purpose. So i am creating a test method and one of the parameters is xml data and i am not sure how to pass it in.
Service
public IEnumerable<Submissions> CheckingOutForUserReview(string data)
{
var _submissions = DataContextManager.StoredProcs.CheckingOutForUserReview<SSubmissions>(data, s => new Submissions
{
QRCodeGUID = SubmissionsColumnMap.QRCodeGUID(s),
StoragePath = SubmissionsColumnMap.StoragePath(s),
UploadedByUsersID = SubmissionsColumnMap.UploadedByUsersID(s)
});
return _submissions;
}
Stored Proc:
public virtual IEnumerable<T> CheckingOutForUserReview<T>(string data, Func<IDataRecord, T> modelBinder)
{
SqlCommand _command = new SqlCommand("dbo.CheckingOutForUserReview");
_command.CommandType = CommandType.StoredProcedure;
_command.Parameters.Add(new SqlParameter { ParameterName = "Data", SqlDbType = SqlDbType.Xml, Value = data });
return DbInstance.ExecuteAs<T>(_command, modelBinder);
}
This is my TestMethod:
public void CheckingOutForUserReview()
{
string _data = #"<CheckingOutForUserReview xmlns:i=""www.w3.org/2001/XMLSchema-instance"" xmlns=""schemas.name.com/2013/03/Malt.Models"">
<Record>
<QRCodeID>2FAC636E-F96C-4465-9272-760BAF73C0DF</QRCodeID>
<SubmissionID>10B5236C-47FD-468D-B88D-D789CA0C663A</SubmissionID>
<UserID>1</UserID>
<Page>1</Page>
</Record>
</CheckingOutForUserReview>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(_data);
var _Svc = new SubmissionsService();
var _checkins = _Svc.CheckingOutForUserReview(doc.InnerXml);
}
UPDATE:
my CheckingOutForUserReview() method accepts a XmlDocument as i changed it to that in my stored procedure and with what i currently have it is giving an error that i have invalid arguments(System.Xml.XmlDocument) not sure if i messed up somewhere.
If this is a different way i am also open in trying new ways. Thanks for the help.
As I see there are two ways:
You should save your xml into an xml file by adding xml file in your
project then use it with XmlDocument using Load method like:
XmlDocument doc = new XmlDocument.Load(FileName);
...
...
var _checkins = _Svc.CheckingOutForUserReview(doc.innerXml);
Save your xml as a string literal and use it with XmlDocument using
LoadXml method like:
XmlDocument doc = new XmlDocument.LoadXml(stringThatContainsXml);
...
...
var _checkins = _Svc.CheckingOutForUserReview(doc.innerXml);
You can use XDocument and XElement classes as well but my focus on XmlDocument is that it will work for framework less than 3.5 too since XDocument and XElement is introduced in framework 3.5.
Also loading xml into a parser will help to filter out the invalid xml. (if mistakenly tried to use)
Another thing i have noticed in your snippet:
Assert.IsNotNull(_data);
It should come before the initialization of _Svc, because if there is no data in _data initialization doesn't make sense.
So your code looks like:
public void CheckingOutForUserReview()
{
string _data = "I want to pass in xml here";
Assert.IsNotNull(_data); <--------------- See the re-ordering
var _Svc = new SubmissionsService();
var _checkins = _Svc.CheckingOutForUserReview(_data);
}
Like I said in a comment, I think the best way to do this is to save the XML into a separate file.
If you don't want to do that, you can use verbatim string literal (note the double quotes):
string data = #"<CheckingOutForUserReview xmlns:i=""www.w3.org/2001/XMLSchema-instance"" xmlns=""schemas.name.com/2013/03/Malt.Models"">
<Record>
<QRCodeID>2FAC636E-F96C-4465-9272-760BAF73C0DF</QRCodeID>
<SubmissionID>10B5236C-47FD-468D-B88D-D789CA0C663A</SubmissionID>
<UserID>1</UserID>
<Page>1</Page>
</Record>
</CheckingOutForUserReview>";
I don't see what is the problem in passing any kind of strings as a parameter into a method
If your XML is generated from your code, you better have used a StringBuilder to build it to reduce creating new references while concatenating your string.
If your XML is originally from a file, pass the file path into your method, and open the document there. there are a lot of different ways to open and read XML documents, or loading a string to an XML document and deal with it as XML rather than a string.
Examples:
http://www.codeproject.com/Articles/24375/Working-with-XML
http://forum.codecall.net/topic/58239-c-tutorial-reading-and-writing-xml-files/
and finally from MSDN:
http://msdn.microsoft.com/en-us/library/aa288481%28v=vs.71%29.aspx
enjoy

Write string to xml file

I save all attachments from an email:
List<Pop3Content> contentList = Pop3Message.GetAttachedContents(client.GetMessage(i).Contents, c => c.IsAttachment == true);
XmlDocument xml=new XmlDocument();
xml.LoadXml(contentList[0].BodyText);
this
contentList[0].BodyText
Returns the whole Content of an attached XML file, the way I want to have it in my XmlDocument XML
But the method LoadXML expects a path to an actual XML file. How can I write strings into an "internal" XML file?
This method accepts string.
You can do
XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");
Read this
I think you need to do this
xml.LoadXml(contentList[0].BodyText.ToString());

Xml within an Xml

I basically want to know how to insert a XmlDocument inside another XmlDocument.
The first XmlDocument will have the basic header and footer tags.
The second XmlDocument will be the body/data tag which must be inserted into the first XmlDocument.
string tableData = null;
using(StringWriter sw = new StringWriter())
{
rightsTable.WriteXml(sw);
tableData = sw.ToString();
}
XmlDocument xmlTable = new XmlDocument();
xmlTable.LoadXml(tableData);
StringBuilder build = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(build, new XmlWriterSettings { OmitXmlDeclaration = true }))
{
writer.WriteStartElement("dataheader");
//need to insert the xmlTable here somehow
writer.WriteEndElement();
}
Is there an easier solution to this?
Use importNode feature in your document parser.
You can use this code based on CreateCDataSection method
// Create an XmlCDataSection from your document
var cdata = xmlTable.CreateCDataSection("<test></test>");
XmlElement root = xmlTable.DocumentElement;
// Append the cdata section to your node
root.AppendChild(cdata);
Link : http://msdn.microsoft.com/fr-fr/library/system.xml.xmldocument.createcdatasection.aspx
I am not sure what you are really looking for but this can show how to merge two xml documents (using Linq2xml)
string xml1 =
#"<xml1>
<header>header1</header>
<footer>footer</footer>
</xml1>";
string xml2 =
#"<xml2>
<body>body</body>
<data>footer</data>
</xml2>";
var xdoc1 = XElement.Parse(xml1);
var xdoc2 = XElement.Parse(xml2);
xdoc1.Descendants().First(d => d.Name == "header").AddAfterSelf(xdoc2.Elements());
var newxml = xdoc1.ToString();
OUTPUT
<xml1>
<header>header1</header>
<body>body</body>
<data>footer</data>
<footer>footer</footer>
</xml1>
You will need to write the inner XML files in CDATA sections.
Use writer.WriteCData for such nodes, passing in the inner XML as text.
writer.WriteCData(xmlTable.OuterXml);
Another option (thanks DJQuimby) is to encode the XML to some XML compatible format (say base64) - note that the encoding used must be XML compatible and that some encoding schemes will increase the size of the encoded document (base64 adds ~30%).

XML Transformation Error - The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type

I keep getting the above error when trying to transform XML that's generated in code to a plain text output.
My .xsl file is:
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>Test</xsl:text>
</xsl:template>
</xsl:transform>
And my C# method code is:
if( !File.Exists( xslPath ) )
throw new Exception( "XSL File (" + xslPath + ") does not exist" );
XslTransform docXsl = new XslTransform();
docXsl.Load( xslPath );
XmlDocument docXml = new XmlDocument();
XmlElement emailNode = docXml.CreateElement("Email");
docXml.AppendChild( emailNode );
XmlResolver xres = null;
XmlReader xr = docXsl.Transform( docXml, null, xres );
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load( xr );
return xmldoc.OuterXml;
The XML generated is very simple, just
<Email/>
If I remove the node from the XSL, then I do not get the error.
I cannot find out why this is happening. Any help would be greatly appreciated.
Thanks
What is it that you want to achieve? If you use .NET 2.0 or later you shouldn't use XslTransform at all, rather XslCompiledTransform. And if you want plain text output then it does not make any sense to try to load that transformation result into an XmlDocument as that object model is meant to contain a well-formed XML document and not some plain text. So that is the reason I think you get the error, your transformation result is plain text with a single text node and then you try to load that single text node into an XmlDocument which looks for a root element which does not exist.
Consider to tell is which .NET version you use/target and what kind of output you want (e.g. plain text file or string with the transformation result), then we can point you to the right overload of the Transform method of XslCompiledTransform http://msdn.microsoft.com/en-us/library/system.xml.xsl.xslcompiledtransform.transform.aspx to get that result.
For instance if your transformation input is an XmlDocument or other object implementing IXPathNavigable you can use http://msdn.microsoft.com/en-us/library/ms163435.aspx to transform to a StringWriter to get an String result as follows:
XslCompiledTransform proc = new XslCompiledTransform();
proc.Load(xslPath);
string result;
using (StringWriter sw = new StringWriter())
{
proc.Transform(docXml, null, sw);
result = sw.toString();
}
return result;

Categories

Resources