|
Latest update (V1.1)
Fixed a bug in the ConvertToLowerCase method that was not working with tag with attributes.
Introduction
This article presents a simple class that can be used to adjust the HTML code generated by ASP.NET in order to make it a valid XHTML document.
A valid XHTML document is a document that has been successfully tested using the W3C Markup Validation Service (see http://validator.w3.org). This free service checks XHTML documents for conformance to W3C recommendations. This is not only useful to guarantee that your site will be correctly managed by any W3C compliant browser, but this kind of compliance could also be a specific requirement coming from your customer.

The problem
The problem is that if you try to create a XHTML document using ASP.NET, you will probably fail since the code generated by the ASP.NET engine is not XHTML.
Just create a simple ASPX page and then run the W3C validator. Here is a list of errors you will find:
Uppercase tags
XHTML is all lower-case and it is case sensitive. Tags like HTML or HEAD are undefined for the XHTML validator. For this kind of problems, you could simply fix it by hand editing the HTML directly using the Visual Studio editor. Unfortunately, each time you add a new control on the page and you go back and forth from the design to the HTML view, the Visual Studio editor make the tags HTML and HEAD all uppercase.
Self-close tags
In XHTML (as in XML), all the tags must have a correspondent close tag or they must be self-close. Tags like <br> or <link href="style.css" rel="stylesheet"> are not XHTML valid. You should use <br /> and <link href="style.css" rel="stylesheet" /> instead.
Deprecated attributes
Some valid HTML attributes have been deprecated by XHTML. For instance, the name attribute is substitute by the id. If you take a look at the ASP.NET HTML code, you will see the following script (that is actually used to handle the ASP.NET postback mechanism). <form name="Form1" method="post" action="Index.aspx" id="Form1">
<input type="hidden" name="__EVENTTARGET" value="" ID="Hidden1"/>
<input type="hidden" name="__EVENTARGUMENT" value="" ID="Hidden2"/>
<input type="hidden" name="__VIEWSTATE"
value="ReuDDhCfGkeYOyM6Eg==" ID="Hidden3"/>
<script language="javascript">
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1
{
theform = document.forms["Form1"];
}
else {
theform = document.Form1;
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
</script>
The form attribute name need to be removed in order to make this code XHTML compliant.
Note that this code is generated only when the page is created. You have no way to change it at design time.
Mandatory attributes
The above script has another problem. In the script tag, the type="text/javascript" attribute is missing. This attribute is mandatory according to the XHTML specification.
Misplaced attributes
Still considering the content of the Form1, the hidden input tags are not correctly placed. In fact, according to XHTML specifications, an input tag has to be inside one of the following tags: "p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "pre", "address", "fieldset", "ins", "del".
The solution
A possible solution is to intercept the HTML code just before it is sent to the client web browser and make the needed corrections.
XHTMLPage class
The XHTMLPage class inherits from the System.Web.UI.Page class, and it overrides the Render method. protected override void Render(HtmlTextWriter output)
{
StringWriter w;
w = new StringWriter();
HtmlTextWriter myoutput = new HtmlTextWriter(w);
base.Render(myoutput);
myoutput.Close();
m_sXHTML = w.GetStringBuilder().ToString();
ReplaceDocType();
switch (m_XHTMLFormat)
{
case _XHTMLFormat.XHTML10_Strict:
ConvertToXHTMLStrict();
break;
case _XHTMLFormat.XHTML10_Transitional:
ConvertToXHTMLTransactional();
break;
}
output.Write(m_sXHTML);
}
In the XHTMPage::Render method, first of all, the base class method base.Render is called using an instance of a new HtmlTextWriter object that has been created locally. The HtmlTextWriter is based on an underlying StringWriter object; in this way, the HTML code generated by ASP.NET can be placed inside the m_sXHTML string and then it can be treated.
The methods ConvertToXHTML… take care of replacing the non-valid XHMTL parts with equivalent XHTML code.
Make your page XHTML valid
In order to make any ASP.NET page an XHTML valid page, you just need to inherit from XHTMLPage instead of System.Web.UI.Page. public class Index : XHTMLPage
The XHTMLPage can be configured using the XHTMLFormat property; this can be set to Strict or Transitional (that is the default) in order to make the page valid according to the XHTML Strict or SHTML Transitional specification. base.XHTMLFormat = XHTMLPage._XHTMLFormat.XHTML10_Strict;
Conclusion
Here I presented a problem that you may meet when trying to get a valid XHTML page using ASP.NET. Could be that this problem will be solved in the next version of Visual Studio, but in the mean time, I presented a simple solution you may find useful.
In the sample code I attached, I did not care too much about performance, but it is obvious that parsing the HTML generated by ASP.NET takes some time.
Credits
- sebmafate helped me in extending and fixing the class functionality.
History
04-Nov-2004
- Fixed a bug in the
ConvertToLowerCase method that was not working with tag with attributes.
13-Oct-2004
- Automatically convert to lowercase all tags and attribute names.
- Added support for XHTML Frameset specification.
- Added support for encoding and language XML attributes.
- Added support for CDATA attributes.
27-Sep-2004
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 63 (Total in Forum: 63) (Refresh) | FirstPrevNext |
|
|
 |
|
|
 |
|
|
Hello Lonely. Great Solution... But i see that the ASP.NET not yet attend 100% the WebStandards. 
Tks a lot.
Rodrigo Kono MCP - MCTS - MSP DevGoiás.NET - www.devgoias.net Brazil
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
VS2003 destroys <ul> <li>item1</li> <li>item2</li> </ul>
into (horrible): <ul> <li>item1 <li>item2 </LI></UL>
XHTMLPage just can handle it (by adding </li> before the second <li> . I don't expect it to do that with such a few lines of code. I mean I can't stop VS2003 from destroying my valid XHTML. I've tried turning off automatic formating but it didn't help.  
MaxGyver
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Well, good code. no doubt.
I convertd the code to VB using the free tool C# to VB.NET converter[^] and implemented my ASP .NET project (written entirely in VB.NET 2005). Executed and it worked, but errors of javascript.
My solution is using Microsoft AJAX and third party controls (www.telerik.com). I think one of them (strongly agree, AJAX) causing problem. I received the following error message:
Assertion Failed: Unrecognized tag script:pagerequestmanager Break into debugger?
any idea?
thanks, Sameers
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
the __viewstate field is not handled, so this class does not do what it should, it does not generate valid xhtml by w3c
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
| Had started using this class and thought it was a fantastic idea and well implemented, but have had to stop using it because it sometimes changes the inner text of HTML tags to lowercase e.g. | My Text | becomes my text |
I haven't been able to find a clear pattern to this behaviour, but does anyone know of a fix?
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
good moning all, i have an application developped with vb.net and i have problem when i browse my application with mozilla, i know that the html generated by vb.net is not valid, in the first time i used the classe aspnet2xhtml to resolved this problem but it's not work, i want to know if this classe can convert to valid html4.0. thank you.
foued69
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Found this article during my search for a way to make ASP.NET xhtml compliant pages for my current project. After looking through the code, I have a few suggestions (without function calling for brevity):
// changing all tags and their attributes to lower case // The [^!?] part will exclude <!DOCTYPE> and <?xml ...?> tags sXhtml = Regex.Replace(sXhtml,"<[^!?].*?>",new MatchEvaluator(Lowerer),RegexOptions.IgnoreCase); // fixing empty tags // processing all empty tags, in case somthing like <br/> is used // instead of <br />. string[] sa = new string[]{"br", "meta", "link", "hr", "img"}; foreach (string s in sa) { sXhtml = Regex.Replace(sXhtml,"<"+s+"(?<attr>\\s*.*?)/?>", "<"+s+"${attr} />",RegexOptions.IgnoreCase); } // fixing <script> tag // The idea is to remove the 'type' attribute first, and then put it back. // This is in case where the 'type' attribute already exists, as in: // <script language="javascript" type="text/javascript" src="/aspnet_client/system_web/1_1_4322/WebUIValidation.js"></script> sXhtml = Regex.Replace(sXhtml, "<script(?<attr1>.*?)(type\\s*=\\s*\"text/javascript\")(?<attr2>.*?)>", "<script${attr1} ${attr2}>", RegexOptions.IgnoreCase); // in case type='text/javascript' is used sXhtml = Regex.Replace(sXhtml, "<script(?<attr1>.*?)(type\\s*=\\s*'text/javascript')(?<attr2>.*?)>", "<script${attr1} ${attr2}>", RegexOptions.IgnoreCase); sXhtml = Regex.Replace(sXhtml, "<script(?<attr>.*?)>", "<script type=\"text/javascript\" ${attr}>", RegexOptions.IgnoreCase); // changing style attributes to lower case // The ? in .+? will take care excessive lower-casing, as pointed out by Mike Tong. sXhtml = Regex.Replace(sXhtml,"style\\s*=\\s*\".+?\"",new MatchEvaluator(StyleLowerer),RegexOptions.IgnoreCase); // removing "name" attribute sa = new string[]{"a", "applet", "form", "frame", "iframe", "img", "map"}; foreach (string s in sa) { sXhtml = Regex.Replace(sXhtml,"<"+s+"(?<attr1>.*?)(name\\s*=\\s*\".*?\")(?<attr2>.*?)>", "<"+s+"${attr1} ${attr2}>",RegexOptions.IgnoreCase); }
And the functions that go with the above:
public static string Lowerer(Match m) { // get something like // <TABLE borderColor="#cc0000" cellSpacing="0" cellPadding="0"> string s = m.ToString(); // check if attributes exist if (Regex.Matches(s,"[^\\s]+\\s*=\\s*\".*?\"").Count>0) { // get everything up to the first attribute, in this case: // <TABLE borderColor= s = Regex.Replace(s,"<.*?=",new MatchEvaluator(ConvertToLower)); // process subsequent attributes, if any. In this case: // " cellSpacing= // and // " cellPadding= s = Regex.Replace(s,"\"[^\"]*?=",new MatchEvaluator(ConvertToLower)); } else { // otherwise change the whole tag to lower case, since // there are no attributes. s = s.ToLower(); } return s; } public static string StyleLowerer(Match m) { // should something like style="FONT-FAMILY:Verdana; FONT-SIZE:13px" string s = m.ToString(); // process the first style attribute, in this case: // "FONT-FAMILY: s = Regex.Replace(s,"\".*?:",new MatchEvaluator(ConvertToLower)); // process subsequent attributes, if any. In this case: // ; FONT-SIZE: s = Regex.Replace(s,";.*?:",new MatchEvaluator(ConvertToLower)); return s; } public static string ConvertToLower(Match m) { return m.ToString().ToLower(); }
One known problem is the extra spaces created, such as <br /> becoming <br />. Or in the script tag processing. Thanks for writing this article!
Vincent Tan
|
| Sign In·View Thread·PermaLink | 5.00/5 (3 votes) |
|
|
|
 |
|
|
 |
 | s |  | Anonymous | 1:49 7 Apr '05 |
|
|
 |
|
|
Because I liked so much this class, i added some improvements to make it work with most pages in validator.w3.org. And I thought I should post it back to Codeproject.
Here is the code with some improvements.. 1. RemoveAttribute, now supports <form bla="test" name="form1" > (with Regex) 2. Works with stringbuilder instead of string.(not tested for improved performance) 3. Added remove of not supported attribute language with select and input. 4. Added ParsePostBack, this function replaces _dopostback javascript (function found on the internet, don't know where.(google) 5. Made sure CDATA works in Explorer en Mozilla for javascript and Stylesheets.
/* * Auteur : big71 (http://www.codeproject.com/aspnet/ASPNET2XHTML.asp) * Mise à jour et adaptation : Sébastien FERRAND (http://www.vbmaf.net) * Description : Transforme le code HTML généré par asp.net pour le rendre * compatible avec XHTML. * Version : 1.0 * Date : 05 octobre 2004 * ------------------------------------------------------------------------------ * Révision : * Version : 1.1 * Date : 03 novembre 2004 * Mise à jour des méthodes ConvertToLowerCase(), SingleTagToLowerCase() et * PropertiesToLowerCase() pour la prise en charge des tags avec ou sans propriété * et les propriétés multiples pour un tag * -- * Add support for tags with/without properties and multiproperties tags. * ------------------------------------------------------------------------------ * Licence : Cette classe est livrée telle quelle. Le ou les auteurs ne sont * en rien responsable de l'utilisation qui en sera fait. * Vous êtes libre de distribuer ou d'utiliser cette classe dans * vos projets à condition que cet entête reste présente. */
using System; using System.IO; using System.Text.RegularExpressions; using System.Text; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Diagnostics; namespace XHTMLPage { /// <summary> /// Summary description for XHTMLPage. /// Please use XHTML10_Transitional, the others need some work. /// </summary> public class XHTMLPage : System.Web.UI.Page { /// <summary> /// Please use XHTML10_Transitional, the others need some work. /// </summary> public enum _XHTMLFormat { XHTML10_Strict, XHTML10_Transitional, XHTML10_Frameset }
private StringBuilder m_sXHTML; private _XHTMLFormat m_XHTMLFormat; private Encoding m_Encoding; private string m_sLanguage; private bool m_bXmlCDATA; /// <summary> /// Please use XHTML10_Transitional, the others need some work. /// </summary> public _XHTMLFormat XHTMLFormat { get {return m_XHTMLFormat;} set {m_XHTMLFormat = value;} }
public Encoding Encoding { get {return m_Encoding;} set {m_Encoding = value;} } public string Language { get {return m_sLanguage;} set {m_sLanguage = value;} } /// <summary> /// This needs some work, please leave it at false. /// </summary> public bool XmlCDATA { get {return m_bXmlCDATA;} set {m_bXmlCDATA = value;} }
public XHTMLPage() { // // TODO: Add constructor logic here // m_sXHTML = new StringBuilder(""); m_XHTMLFormat = _XHTMLFormat.XHTML10_Transitional; m_Encoding = Encoding.UTF8; m_sLanguage = "en"; m_bXmlCDATA = false; }
protected override void Render(HtmlTextWriter output) {
StringWriter w; w = new StringWriter(); HtmlTextWriter myoutput = new HtmlTextWriter(w); //Get the html: base.Render(myoutput);
myoutput.Close();
m_sXHTML = w.GetStringBuilder(); //Filter the content ReplaceDocType();
switch (m_XHTMLFormat) { case _XHTMLFormat.XHTML10_Strict: ConvertToXHTMLStrict(); break;
case _XHTMLFormat.XHTML10_Transitional: ConvertToXHTMLTransitional(); break;
case _XHTMLFormat.XHTML10_Frameset: ConvertToXHTMLFrameset(); break; } output.Write(m_sXHTML); }
private void ConvertToXHTMLFrameset() { ConvertToLowerCase(); AddSelfClose("meta"); FixHtml(); }
private void ConvertToXHTMLTransitional() { ConvertToLowerCase(); AddSelfClose("meta"); AddSelfClose("link"); AddSelfClose("img"); AddSelfClose("hr"); AddSelfClose("input"); RemoveAttribute("form","language"); RemoveAttribute("select","language"); RemoveAttribute("input","language"); FixScript(); FixBr(); FixStyle(); FixHtml(); }
private void ConvertToXHTMLStrict() { ConvertToLowerCase(); AddSelfClose("meta"); AddSelfClose("link"); AddSelfClose("img"); AddSelfClose("hr"); AddSelfClose("input");
FixScript(); RemoveAttribute("form", "name"); RemoveAttribute("form","language"); RemoveAttribute("select","language"); RemoveAttribute("input","language"); FixInput(); FixBr(); FixStyle(); FixHtml(); maskScript(); }
private void ReplaceDocType() { // delete the current DOCTYPE int nStart = m_sXHTML.ToString().IndexOf("<!DOCTYPE", 0); if ( nStart > 0 ) { int nEnd = m_sXHTML.ToString().IndexOf(">", nStart + 1); if ( nEnd > 0 ) { m_sXHTML = m_sXHTML.Remove(nStart, nEnd-nStart+1);
switch (m_XHTMLFormat) { case _XHTMLFormat.XHTML10_Strict: m_sXHTML = m_sXHTML.Insert(0, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"); break;
case _XHTMLFormat.XHTML10_Transitional: m_sXHTML = m_sXHTML.Insert(0, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); break;
case _XHTMLFormat.XHTML10_Frameset: m_sXHTML = m_sXHTML.Insert(0, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">"); break; } //m_sXHTML = m_sXHTML.Insert(0, "<?xml version=\"1.0\" encoding=\""+ m_Encoding.HeaderName +"\"?>\r\n"); } } }
private void ConvertToLowerCase() { // Make all tag to lower case // m_sXHTML = Regex.Replace(m_sXHTML, "<(/?)([a-zA-Z]+)(\\s*)>", new MatchEvaluator(SingleTagToLowerCase), RegexOptions.IgnoreCase); /// Update 03/11/2004 : Add support for Tags with properties /// Author : Sébastien FERRAND (mailto:sebastien.ferrand@vbmaf.net) m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), "<(/?)([a-zA-Z0-9]+)[ ]*(.*?)>", new MatchEvaluator(SingleTagToLowerCase), RegexOptions.IgnoreCase)); /// Update 03/11/2004 : Update to match correctly tag with more one propertie /// Author : Sébastien FERRAND (mailto:sebastien.ferrand@vbmaf.net) // Make all properties to lower case m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), "<([a-zA-Z0-9]+)(\\s+[a-zA-Z]+)(=\".+?> ", new MatchEvaluator(PropertiesToLowerCase), RegexOptions.IgnoreCase)); }
private string SingleTagToLowerCase(Match m) { /// Update 03/11/2004 : Add support for Tags with multi-properties /// Author : Sébastien FERRAND (mailto:sebastien.ferrand@vbmaf.net) if (m.Groups[3].ToString().Trim() == String.Empty ) return "<" + m.Groups[1].ToString().ToLower() + m.Groups[2].ToString().ToLower() + ">"; else return "<" + m.Groups[1].ToString().ToLower() + m.Groups[2].ToString().ToLower() + " " + m.Groups[3].ToString() + ">"; }
private string PropertiesToLowerCase(Match m) { string szReplace = ""; szReplace = "<" + m.Groups[1].ToString() + m.Groups[2].ToString().ToLower();
// Search another property in tag if (Regex.Match(m.Groups[3].ToString(), "(.*?\")(\\s+\\w+)(=\".+> ", RegexOptions.IgnoreCase).Success) { szReplace += Regex.Replace(m.Groups[3].ToString(), "(.*?\")(\\s+\\w+)(=\".+> ", new MatchEvaluator(nextProperty), RegexOptions.IgnoreCase); } else { szReplace += m.Groups[3].ToString(); }
return szReplace ; }
/// <summary> /// Recursively search for property in tag /// </summary> /// <param name="m">Match of the regular expression</param> /// <returns>tag with lower case properties</returns> private string nextProperty(Match m) { string szReplace = ""; szReplace = m.Groups[1].ToString() + m.Groups[2].ToString().ToLower();
// Search another property in tag // Ignore if tag contains __VIEWSTATE... prevent long time calculation. if (Regex.Match(m.Groups[3].ToString(), "(.*?\")(\\s+\\w+)(=\".+> ", RegexOptions.IgnoreCase).Success && m.Groups[3].ToString().IndexOf("__VIEWSTATE")==-1) { System.Diagnostics.Debug.WriteLine("Match OK","nextProperty"); szReplace += Regex.Replace(m.Groups[3].ToString(), "(.*?\")(\\s+\\w+)(=\".+> ", new MatchEvaluator(nextProperty), RegexOptions.IgnoreCase); } else { System.Diagnostics.Debug.WriteLine("Match NOK","nextProperty"); szReplace += m.Groups[3].ToString(); } return szReplace; }
private string HTMLTag(Match m) { return "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\""+ m_sLanguage +"\">"; }
private void FixHtml() { m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), "<html>", new MatchEvaluator(HTMLTag), RegexOptions.IgnoreCase)); }
private void FixBr() { m_sXHTML = m_sXHTML.Replace("<br>", "<br />"); }
private void FixScript() { m_sXHTML = m_sXHTML.Replace("<script language=\"javascript\">", "<script type=\"text/javascript\">"); }
private void FixStyle() { m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), "style=\"[^\"]+\"", new MatchEvaluator(ToLowerCase), RegexOptions.IgnoreCase));
//m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), "style=\".+\"", new MatchEvaluator(ToLowerCase), RegexOptions.IgnoreCase));
// // Add <![CDATA[ ... ]]> to mask style m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), @"(<style[^<]*> {1}(?(?=\s*<!--)(\s*<!--)(\s*.*?)(//\s*--> |(\s*.*?))\s*(</style> {1}", new MatchEvaluator(FixStyleElv), RegexOptions.IgnoreCase | RegexOptions.Singleline)); }
private void FixInput() { int nStart = 0; int nPos = 0; while ( nPos >= 0 ) { string sSearch = "<input type=\"hidden\""; nPos = m_sXHTML.ToString().IndexOf(sSearch, nStart); if ( nPos > 0 ) { nStart = nPos + sSearch.Length; m_sXHTML = m_sXHTML.Insert(nPos, "<pre>");
int nEnd = m_sXHTML.ToString().IndexOf(">", nStart); if ( nEnd > 0 ) { m_sXHTML = m_sXHTML.Insert(nEnd+1, "</pre>"); } } } }
private void AddSelfClose(string sTagName) { int nStart = 0; int nPos = 0; while ( nPos >= 0 ) { string sSearch = "<" + sTagName; nPos = m_sXHTML.ToString().IndexOf(sSearch, nStart); if ( nPos > 0 ) { nStart = nPos + 1; int nEnd = m_sXHTML.ToString().IndexOf(">", nStart); if ( nEnd > 0 ) { if ( m_sXHTML[nEnd-1] != '/' ) { m_sXHTML = m_sXHTML.Insert(nEnd, " /"); } } } } }
private void RemoveAttribute(string sTagName, string sAttrName) { int nStart = 0; int nLen = 0; int nErased=0; foreach(Match m in Regex.Matches(m_sXHTML.ToString(),"<" +sTagName+ @"((?'attrib'(\s*(\w*)\s*=\s*(?'quo'(""|'))(.*?)\k'quo'))*?)(\s/){0,1}>")) { for(int i=0;i<m.Groups["attrib"].Captures.Count;i++) { Capture g =m.Groups["attrib"].Captures[i]; if(g.Value.Trim().IndexOf(sAttrName)>=0) { Debug.WriteLine("remove:" +sAttrName+ " from " + m.Value); nStart = g.Index -nErased; nLen = g.Length; m_sXHTML = m_sXHTML.Remove(nStart, nLen); nErased = nErased + nLen; } } } }
private void maskScript() { // Add <![CDATA[ ... ]]> to mask script m_sXHTML = new StringBuilder(Regex.Replace(m_sXHTML.ToString(), @"(<script[^<]*> {1}(?(?=\s*<!--)(\s*<!--)(\s*.*?)(//\s*--> |(\s*.*?))\s*(</script> {1}", new MatchEvaluator(FixScriptElv), RegexOptions.IgnoreCase | RegexOptions.Singleline)); } private string FixStyleElv(Match m) { string ret=""; string st, ed;
if (m_bXmlCDATA) { st = "\r\n/*<![CDATA[ */\r\n"; ed = "\r\n/*]]>*/\r\n"; } else { st = "\r\n<!--\r\n"; ed = "\r\n//-->\r\n"; }
if (m.Groups[2].ToString().Trim()=="" && m.Groups[4].ToString().Trim()=="") st = ed = "";
ret = m.Groups[1].ToString() + st; ret += m.Groups[2].ToString() + m.Groups[4].ToString() + ed + m.Groups[5].ToString(); return ret; } private string FixScriptElv(Match m) { string ret=""; string st, ed;
if (m_bXmlCDATA) { st = "\r\n// <![CDATA[\r\n"; ed = "\r\n// ]]>\r\n"; } else { st = "\r\n<!--\r\n"; ed = "\r\n//-->\r\n"; }
if (m.Groups[2].ToString().Trim()=="" && m.Groups[4].ToString().Trim()=="") st = ed = "";
ret = m.Groups[1].ToString() + st; ret += ParsePostBack(m.Groups[2].ToString()) + m.Groups[4].ToString() + ed + m.Groups[5].ToString(); return ret; } private const string XHmlPostBack = "function __doPostBack(eventTarget, eventArgument){{var theform = document.getElementById (\"{0}\");theform.__EVENTTARGET.value = eventTarget.split(\"$\").join(\":\");theform.__EVENTARGUMENT.value = eventArgument;theform.submit();}}"; private string ParsePostBack(string sRoutine) { if (sRoutine.IndexOf("__doPostBack(eventTarget, eventArgument)") == -1) return sRoutine; //Replacae PostBackRoutine // I think we can replace it this way ///function __doPostBack(eventTarget, eventArgument){ ///var theform = document.getElementById ('_ctl0'); ///theform.__EVENTTARGET.value = eventTarget.split("$").join(":"); ///theform.__EVENTARGUMENT.value = eventArgument;theform.submit(); ///} Match FormNameMatch = Regex.Match (sRoutine,"document.forms\\[\"([^\"]*)\"\\]",RegexOptions.IgnoreCase | RegexOptions.Singleline); string FormName; if (FormNameMatch.Success) FormName = FormNameMatch.Groups[1].ToString(); else FormName = "Form1"; return String.Format(XHmlPostBack,FormName);
} private string ToLowerCase(Match m) { return m.ToString().ToLower(); }
} }
|
| | | | |