Getting Variable values out of and XSLT file - c#

I wanted to find out if there is a way of getting a parameter or variable value out of an XSL file. For example, if I have the following:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="username" select ="usertest"/>
<xsl:variable name="password" select ="pass"/>
<!-- ... -->
</xsl:stylesheet>
I would like to read the username and password values from the XSL and use them for authentication. I am using ASP.Net and C# to perform the actual transform on an XML file.
Could someone please share code with me that would allow me to read the XSL variables from ASP.NET/C#. Thanks in advance for the help.

This is easy. XSL files are XML themselves, so you can treat them as such.
XmlDocument xslDoc = new XmlDocument();
xslDoc.Load("myfile.xsl");
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xslDoc.NameTable);
nsMgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
XmlNode usrNode = xslDoc.SelectSingleNode("/xsl:stylesheet/xsl:variable[#name='username']", nsMgr);
XmlNode pwdNode = xslDoc.SelectSingleNode("/xsl:stylesheet/xsl:variable[#name='password']", nsMgr);
string usr = usrNode.Attributes["select"].Value;
string pwd = pwdNode.Attributes["select"].Value;

Your question is (edit: was) missing the actual code, but from the description it appears what you are looking for is XPath. XSL will transform one XML document into another XML document, you can then use XPath to query the resulting XML to get out the values that you want.
This Microsoft KB article has information about how to use XPath from C#:
http://support.microsoft.com/kb/308333

Thanks Everone. Here is what finally worked:
Client (asp with vbscript) Used for Testing Purposes:
<%
//Create Object
Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
//Set up the object with the URL
'xmlhttp.open "POST" ,"http://localhost/ASP_Test/receiveXML.asp",False
//Create DOM Object
Set xmldom = CreateObject("Microsoft.XMLDOM")
xmldom.async = false
//Load xls to send over for transform
xmldom.load(Server.MapPath("/ASP_Test/masterdata/test.xsl"))
//Send transform file as DOM object
xmlhttp.send xmldom
%>
//////////////////////////////////////////////////////////////////////////
On the Server Side: (aspx with C#) Accepts xslt and process the transform:
//file path for data xml
String xmlFile = ("\\masterdata\\test.xml");
//file path for transformed xml
String xmlFile2 = ("\\masterdata\\out.xml");
XmlTextReader reader = new XmlTextReader(Request.InputStream);
Transform(xmlFile, reader, xmlFile2);
public static string Transform(string sXmlPath, XmlTextReader xslFileReader, string outFile)
{
try
{
//load the Xml doc
XPathDocument myXPathDoc = new XPathDocument(sXmlPath);
XslCompiledTransform myXslTrans = new XslCompiledTransform();
//load the Xsl
myXslTrans.Load(xslFileReader);
//create the output stream
XmlTextWriter myWriter = new XmlTextWriter
(outFile, null);
//do the actual transform of Xml
myXslTrans.Transform(myXPathDoc, null, myWriter);
myWriter.Close();
return "Done";
}
catch (Exception e)
{
return e.Message;
}
}

Related

exception occurs while saving XML using c#

I am trying to update an existing XML file by adding a new child node using c#.
Everything is OK if I save it by new name but I want to update the same file and while doing it, got the following exception:
System.IO.IOException:Process cannot access the file... because it is
being used by another process
Here is my code: (I am trying to add a new default node)
XmlDocument doc = new XmlDocument();
string path = #"C:\Debug\default.xml";
doc.Load(path);
XmlNode NName = doc.CreateElement("default");
XmlNode SNO = doc.CreateElement("SNo");
SNO.InnerText = "2";
NName.AppendChild(SNO);
doc.DocumentElement.AppendChild(NName);
doc.Save(path);
Also XML file:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<default>
<SNo>1</SNo>
</default>
</NewDataSet>
If you are sure the file is only being used by your process, then simply read it into a byte array, close the file, then save it again:
(I am using .net 4.0 for this sample):
XmlDocument doc = new XmlDocument();
byte[] content = File.ReadAllBytes(path);
using (var memStream = new MemoryStream(content))
{
doc.Load(memStream);
}
XmlNode NName = doc.CreateElement("default");
XmlNode SNO = doc.CreateElement("SNo");
SNO.InnerText = "2";
NName.AppendChild(SNO);
doc.DocumentElement.AppendChild(NName);
doc.Save(path);

How to transform an xml structure generated from a request to a web services

I have a string var that store an xml from a request to a RESTful service.
I have a problem transforming this with an xslt file on a fly without saving it.
I am getting this error
System.UriFormatException: Invalid URI: The Uri scheme is too long. On this line
xslt.Transform(xmldoc, null, writer);
string xmldoc = xReq("http://restful.com/RestAPI");
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(#"C:\Users\XSeXml\xRes.xslt");
string htmlOutput;
StringWriter writer = new StringWriter();
xslt.Transform(xmldoc, null, writer);
htmlOutput = writer.ToString();
Literal1.Text = htmlOutput;
writer.Close();
How to transform XML as a string w/o using files in .NET?
Ideas from the link above helps to overcome the problem by passing the string to the XmlReader before transforming it.

Save XML Response into Session in C#

I need to save the xml response into sesssion. but I have tried this But It didn't . but I Have save xml request as session It worked. I Have attached working and non working code. can any one please help me on this. I don't want save the xml response as file.
Working Code
String xmltest = Session["xmlreq"].ToString();
SoapClient soap = new SoapClient();
string prueba = soap.RequestResponseMethod("getHotelValuedAvail", xmltest);
string tham = HttpUtility.HtmlDecode(prueba);
XmlDocument doc = new XmlDocument();
doc.LoadXml(tham);
doc.Save(Server.MapPath("hotelrs.xml"));
XslTransform myXslTransform;
myXslTransform = new XslTransform();
myXslTransform.Load(Server.MapPath("hotel.xsl"));
myXslTransform.Transform(Server.MapPath("hotelrs.xml"), Server.MapPath("transformhotels.xml"));
Non working Code
String xmltest = Session["xmlreq"].ToString();
SoapClient soap = new SoapClient();
string prueba = soap.RequestResponseMethod("getHotelValuedAvail", xmltest);
string tham = HttpUtility.HtmlDecode(prueba);
Session.Add("xmlrs", tham);
XmlDocument doc = new XmlDocument();
doc.LoadXml(Session["xmlrs"].ToString());
//doc.Save(Server.MapPath("hotelrs.xml"));
XmlDocument trdoc = new XmlDocument();
XslTransform myXslTransform;
myXslTransform = new XslTransform();
myXslTransform.Load(Server.MapPath("hotel.xsl"));
myXslTransform.Transform(doc.InnerXml, trdoc.InnerXml);
Session.Add("xmltrs", trdoc.InnerXml);
1.Declare a variable.
2.store ur xml request data in that variable.
3.Declare another variable say (String Result).
4.Now Result="Call ur method here which will give u a xml response".
5.Session["Outcome"]=Result;
6.No need to use any XMLDocument here.
If u want to format ur XML response, use XSLT template.
In aspx page
<div id="DivLoad">
<asp:Xml ID="xmlDaynamic" runat="server" Visible="true"></asp:Xml>
</div>
In cs
xmlDaynamic.DocumentContent = session["outcome"];
xmlDaynamic.TransformSource = "yourxslttemplate.xslt";
Hope this will help you.

I have an xml file that is styled with xslt to produce html email template. How can i get that xml as html email body in c#?

I have an xml file that is styled with xslt to produce html email template. I get values from users dynamically and replace xml elements text with the values received. How can i get that xml file and send as html email body in c#?
My Xml Looks Like This
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="EmailTemplateStyleForHTML.xslt"?>
<EmailTemplate>
<subject>Information from xyz</subject>
<displayName>abcd</displayName>
<Message1>
Thanks you for registering to xyz.
</Message1>
<Copyright>Copyright xyz</Copyright>
</EmailTemplate>
I am using LINQ to set the values to the xml.
Note: I know how to get and set the values from xml but what i want is to grab the whole xml file in to the email body.
If you think there is a better approach for this i would love to hear that. I would really appreciate your help.
Edited after Reply:
The xsl transformation part :
TextReader tr1 = new StringReader(#"EMailTemplateHtml.xml");
var tr11 = new XmlTextReader(tr1);
var xPathDocument = new XPathDocument(tr11);
//read XSLT
TextReader tr2 = new StringReader(#"EmailTemplateStyleForHTML.xslt");
var tr22 = new XmlTextReader(tr2);
var xslt = new XslTransform();
xslt.Load(tr22);
var sb = new StringBuilder();
TextWriter tw = new StringWriter(sb);
xslt.Transform(xPathDocument, null, tw);
emailBody = sb.ToString();
I am doing the transformation as you said(#Roy Ashbrook) am i missing anything here?
I believe you will need to actually perform the XSL transform in memory, not reference it in the XML itself. It's possible you could store the XSL in a remote location and reference it that way, but I wouldn't
so:
inject your values into your xml string
transform your xml using your xsl
make that your html message body
Here is some code. Mostly borrowed from/inspired by:
How to transform XML as a string w/o using files in .NET? and Sending E-mail using C#.
void Main()
{
SendHtmlBody(GetHtmlBody());
}
void SendHtmlBody(string HtmlBody){
using(SmtpClient c = new SmtpClient())
{
//set smtp options here
using(MailMessage msg = new MailMessage("from#replace.me","to#replace.me"))
{
msg.Subject = "Testing Bulk mail application";
msg.Body = HtmlBody;
msg.IsBodyHtml = true;
//c.Send(msg);
}
}
}
string GetHtmlBody(){
string xmlInput = #"<?xml version=""1.0"" encoding=""utf-8"" ?>
<EmailTemplate>
<subject>Information from xyz</subject>
<displayName>abcd</displayName>
<Message1>
Thanks you for registering to xyz.
</Message1>
<Copyright>Copyright xyz</Copyright>
</EmailTemplate>";
string xslInput = #"<?xml version=""1.0"" encoding=""ISO-8859-1""?>
<xsl:stylesheet version=""1.0""
xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:template match=""/"">
<html>
<body>
<h5><xsl:value-of select=""EmailTemplate/subject""/></h5>
<h5><xsl:value-of select=""EmailTemplate/displayName""/></h5>
</body>
</html>
</xsl:template>
</xsl:stylesheet>";
using (StringReader srt = new StringReader(xslInput)) // xslInput is a string that contains xsl
using (StringReader sri = new StringReader(xmlInput)) // xmlInput is a string that contains 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);
return sw.ToString();
}
}
}
}

XSLT to transform HTML to Markdown not working

I'm using the XSLT found here to transform content in HTML to Markdown format but the results I'm getting are plain text without the Markdown formatting syntax. Here's the function I'm using:
private static string ConvertToText()
{
string text = string.Empty;
XmlDocument xsl = new XmlDocument();
xsl.CreateEntityReference("nbsp");
xsl.Load(System.Web.HttpContext.Current.Server.MapPath("/Test/markdown.xslt"));
XmlReader xr = XmlReader.Create(System.Web.HttpContext.Current.Server.MapPath("/Test/html.xml"));
//creating stringwriter
StringWriter writer = new System.IO.StringWriter();
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsl);
xslt.Transform(xr, null, writer);
//return string
text = writer.ToString();
writer.Close();
return text;
}
Can anyone tell me why it's not working?
Thanks.
I guess your problem is the xmlns in your input XML. Try either to remove it in the xr variable before you transform it or to adjust your XSL file with namespace declarations like:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/1999/xhtml">
...
<xsl:template match="html:h3">
...

Categories