StringBuilder sbuf = new StringBuilder();
XmlTextWriter writer = new XmlTextWriter(new StringWriter(sbuf));
xslt.Transform(xdoc, null, writer);
writer.Close();
利用StringBuilder对象和StringWriter对象即可。
sbuf.ToString()可得到XML的字符串表示
StringReader txtReader;
txtReader = new StringReader(cleanedMarkUp);
XPathDocument xdoc = new XPathDocument(txtReader);
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("msg.xsl");
XmlTextWriter writer = new XmlTextWriter(new StreamWriter("d:/r.xml"));
xslt.Transform(xdoc, null, writer);
writer.Close();
在一个程序中,要用到如下的XSL用于XSLT转换
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8"/>
<xsl:template match="/">
<messages>
<xsl:for-each select="//tr[@bgcolor='#f3f2f1' and position()>=3 and position()<last()]">
<message>
<msgid>
<xsl:value-of select="td[1]/div/input/@value"/>
</msgid>
<teacher>
<xsl:value-of select="td[3]/div"/>
</teacher>
<content>
<xsl:value-of select="td[4]/div"/>
</content>
<timestamp>
<xsl:value-of select="td[6]/div"/>
</timestamp>
</message>
</xsl:for-each>
</messages>
</xsl:template>
</xsl:stylesheet>
在.NET中报错,出错信息为:
未处理 System.Xml.Xsl.XslLoadException
Message="XSLT 编译错误。"
Source="System.Data.SqlXml"
LineNumber=6
LinePosition=81
SourceUri="file:///D:/myprog/C%23/jxlltEasy/jxlltEasy/bin/Debug/msg.xsl"
StackTrace:
在 System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(XmlReader reader, Boolean include)
在 System.Xml.Xsl.Xslt.XsltLoader.Load(Compiler compiler, Object stylesheet, XmlResolver xmlResolver)
在 System.Xml.Xsl.Xslt.Compiler.Compile(Object stylesheet, XmlResolver xmlResolver, QilExpression& qil)
在 System.Xml.Xsl.XslCompiledTransform.CompileXsltToQil(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
在 System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
在 System.Xml.Xsl.XslCompiledTransform.Load(String stylesheetUri)
在 jxlltEasy.jxlltForm.btnRefresh_Click(Object sender, EventArgs e) 位置 D:\myprog\C#\jxlltEasy\jxlltEasy\jxlltForm.cs:行号 120
在 System.Windows.Forms.Control.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
在 System.Windows.Forms.Button.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.Run(Form mainForm)
在 jxlltEasy.Program.Main() 位置 D:\myprog\C#\jxlltEasy\jxlltEasy\Program.cs:行号 18
在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Xml.XmlException
Message="“<”(十六进制值 0x3C)是无效的属性字符。 行 6,位置 81。"
Source="System.Xml"
LineNumber=6
LinePosition=81
SourceUri="file:///D:/myprog/C%23/jxlltEasy/jxlltEasy/bin/Debug/msg.xsl"
StackTrace:
在 System.Xml.XmlTextReaderImpl.Throw(Exception e)
在 System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
在 System.Xml.XmlTextReaderImpl.Throw(Int32 pos, String res, String[] args)
在 System.Xml.XmlTextReaderImpl.ParseAttributeValueSlow(Int32 curPos, Char quoteChar, NodeData attr)
在 System.Xml.XmlTextReaderImpl.ParseAttributes()
在 System.Xml.XmlTextReaderImpl.ParseElement()
在 System.Xml.XmlTextReaderImpl.ParseElementContent()
在 System.Xml.XmlTextReaderImpl.Read()
在 System.Xml.Xsl.Xslt.XsltInput.ReadNextSiblingHelper()
在 System.Xml.Xsl.Xslt.XsltInput.ReadNextSibling()
在 System.Xml.Xsl.Xslt.XsltInput.MoveToFirstChildAny()
在 System.Xml.Xsl.Xslt.XsltInput.MoveToFirstChild()
在 System.Xml.Xsl.Xslt.XsltLoader.LoadInstructions(List`1 content, InstructionFlags flags)
在 System.Xml.Xsl.Xslt.XsltLoader.LoadLiteralResultElement(Boolean asStylesheet)
在 System.Xml.Xsl.Xslt.XsltLoader.LoadInstructions(List`1 content, InstructionFlags flags)
在 System.Xml.Xsl.Xslt.XsltLoader.LoadTemplate(NsDecl stylesheetNsList)
在 System.Xml.Xsl.Xslt.XsltLoader.LoadRealStylesheet()
在 System.Xml.Xsl.Xslt.XsltLoader.LoadDocument()
在 System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(XmlReader reader, Boolean include)
InnerException:
在Java中,出错信息为:
Fatal Error] :6:80: The value of attribute "select" associated with an element type "xsl:for-each" must not contain the '<' character.
Exception in thread "main" org.xml.sax.SAXParseException: The value of attribute "select" associated with an element type "xsl:for-each" must not contain the '<' character.
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at cn.ldsoft.xpath.XMLHelper.parseXMLFromInputSource(XMLHelper.java:70)
at cn.ldsoft.xpath.XMLHelper.parseXMLFromFile(XMLHelper.java:62)
at cn.ldsoft.simple.Test.main(Test.java:22)
通过查阅资料得知,
将position()<last()改为position() < last(), 问题解决
StringReader txtReader;
txtReader = new StringReader(cleanedMarkUp);
XPathDocument xdoc = new XPathDocument(txtReader);
XPathNavigator nav = xdoc.CreateNavigator();
nav.MoveToRoot();
XPathExpression expr = nav.Compile("//tr[@bgcolor='#f3f2f1']");
XPathNodeIterator node = nav.Select(expr);
while (node.MoveNext())
MessageBox.Show(node.Current.Value);
TidyNet(http://sourceforge.net/projects/tidynet/)是用c#编写的Tidy API,对字符支持比较好,不会出现像NTidy那样的乱码。
Tidy doc = new Tidy();
TidyMessageCollection tmc = new TidyMessageCollection();
MemoryStream input = new MemoryStream();
MemoryStream output = new MemoryStream();
//Set some Tidy options, refer to the HTML Tidy docs for more info
doc.Options.DocType = DocType.Strict;
doc.Options.Xhtml = false;
doc.Options.LogicalEmphasis = true;
doc.Options.DropFontTags = true;
doc.Options.DropEmptyParas = true;
doc.Options.QuoteAmpersand = true;
doc.Options.TidyMark = true;
doc.Options.MakeClean = true;
doc.Options.IndentContent = true;
doc.Options.SmartIndent = true;
doc.Options.Spaces = 4;
doc.Options.WrapLen = 100;
doc.Options.CharEncoding = CharEncoding.UTF8;
doc.Options.XmlOut = true;
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(restext);
input.Write(byteArray, 0, byteArray.Length);
input.Position = 0;
doc.Parse(input, output, tmc);
foreach (TidyMessage message in tmc)
{
if (message.Level == MessageLevel.Error)
{
throw new ApplicationException(String.Format("{0} at line {1} column {2}",
message.Message, message.Line,
message.Column));
}
}
string cleanedMarkUp = System.Text.Encoding.UTF8.GetString(output.ToArray());
NTidy(http://sourceforge.net/projects/ntidy/)是一个用C++编写的供.NET使用的tidy api. 将NTidy.dll添加到项目引用,并添加
using NTidy; 后即可使用
TidyDocument tdoc = new TidyDocument();
tdoc.LoadConfig("tidy.cfg");
tdoc.SetCharEncoding("gb2312");
TidyStatus status = tdoc.LoadString(restext);
tdoc.CleanAndRepair();
XmlDocument xmldoc = new XmlDocument();
xmldoc.InnerXml = tdoc.Root.Value;
问题:没有考虑编码的问题,中文会被自动转换为类似#C2C8;这样的Unicode编码。
tidy.cfg工具可通过TidyGUI工具(http://pagesperso-orange.fr/ablavier/TidyGUI/)生成。
// HTML Tidy configuration file created by TidyGUI
new-inline-tags: o:p
char-encoding: utf-8
doctype: strict
tidy-mark: no
word-2000: yes
output-xml: yes
output-xhtml: yes
add-xml-decl: yes
assume-xml-procins: yes
参考资料:
.NET中的WebClient组件,通过向网站发送登录请求成功后不能保持session。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace jxlltEasy
{
class HttpClient : WebClient
{
// Cookie 容器
private CookieContainer cookieContainer;
/**/
/// <summary>
/// 创建一个新的 WebClient 实例。
/// </summary>
public HttpClient()
{
this.cookieContainer = new CookieContainer();
}
/**/
/// <summary>
/// 创建一个新的 WebClient 实例。
/// </summary>
/// <param name="cookie">Cookie 容器</param>
public HttpClient(CookieContainer cookies)
{
this.cookieContainer = cookies;
}
/**/
/// <summary>
/// Cookie 容器
/// </summary>
public CookieContainer Cookies
{
get { return this.cookieContainer; }
set { this.cookieContainer = value; }
}
/**/
/// <summary>
/// 返回带有 Cookie 的 HttpWebRequest
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
HttpWebRequest httpRequest = request as HttpWebRequest;
httpRequest.CookieContainer = cookieContainer;
}
return request;
}
}
}