假设有下面一个XML文件Bank.xml
<!--Bank.xml -->
<Bank>
<Account>
<AccountNo>1</AccountNo>
<Name>AA</Name>
<Balance>5864.55</Balance>
</Account>
<Account>
<AccountNo>2</AccountNo>
<Name>BB</Name>
<Balance>2654.56</Balance>
</Account>
.......
......
<Account>
<AccountNo>26</AccountNo>
<Name>ZZ</Name>
<Balance>95648.26</Balance>
</Account>
</Bank>我现在利用XPath查询,Button1用来读取查询后的数据写如ListBox1中,Button2用来生成新的子XML文档,例如一个Name可能有好几个Account。比如我要显示AA的所有Account信息,使其生成新的一个XMl文件new.xml,并希望邦定到页面上。
private void Button1_Click(object sender, System.EventArgs e)
{
XPathDocument Doc = new XPathDocument(Server.MapPath("../WebApplication1/XMLData/Bank.xml"));
XPathNavigator myNav = Doc.CreateNavigator();
string name=TextBox1.Text;
XPathNodeIterator myIter = myNav.Select("Bank/Account[child::Name='"+name+"']/AccountNo"); while(myIter.MoveNext())
{
ListBox1.Items.Add(myIter.Current.Value);
} } private void Button2_Click(object sender, System.EventArgs e)
{
XmlTextWriter myWriter =new XmlTextWriter(Server.MapPath("../WebApplication1/XMLData/new.xml"),null);
myWriter.Formatting=Formatting.Indented;
//开始一个文档
myWriter.WriteStartDocument(); //write the comment
myWriter.WriteComment("这是一个子查询例子");
for(int i=1;i<ListBox1.Items.Count;i++)
{
myWriter.WriteStartElement("AccountNo","");
string b=ListBox1.Items[0].Text;
myWriter.WriteString(b);
myWriter.WriteEndElement();
}
myWriter.WriteEndDocument();
myWriter.Flush();
myWriter.Close(); Response.Redirect(Server.MapPath("../WebApplication1/XMLData/new.xml"));
}
我的问题时这样会发生错误,提示为:处于状态 Epilog 的标记 StartElement 将导致无效的 XML 文档。错误发生在 myWriter.WriteStartElement("AccountNo","");
请问这是什么错误,如何解决?还有什么办法适用XPath来查询,从而将自查询结果显示在叶面上的,最好使用DataGrid这些控件?
<!--Bank.xml -->
<Bank>
<Account>
<AccountNo>1</AccountNo>
<Name>AA</Name>
<Balance>5864.55</Balance>
</Account>
<Account>
<AccountNo>2</AccountNo>
<Name>BB</Name>
<Balance>2654.56</Balance>
</Account>
.......
......
<Account>
<AccountNo>26</AccountNo>
<Name>ZZ</Name>
<Balance>95648.26</Balance>
</Account>
</Bank>我现在利用XPath查询,Button1用来读取查询后的数据写如ListBox1中,Button2用来生成新的子XML文档,例如一个Name可能有好几个Account。比如我要显示AA的所有Account信息,使其生成新的一个XMl文件new.xml,并希望邦定到页面上。
private void Button1_Click(object sender, System.EventArgs e)
{
XPathDocument Doc = new XPathDocument(Server.MapPath("../WebApplication1/XMLData/Bank.xml"));
XPathNavigator myNav = Doc.CreateNavigator();
string name=TextBox1.Text;
XPathNodeIterator myIter = myNav.Select("Bank/Account[child::Name='"+name+"']/AccountNo"); while(myIter.MoveNext())
{
ListBox1.Items.Add(myIter.Current.Value);
} } private void Button2_Click(object sender, System.EventArgs e)
{
XmlTextWriter myWriter =new XmlTextWriter(Server.MapPath("../WebApplication1/XMLData/new.xml"),null);
myWriter.Formatting=Formatting.Indented;
//开始一个文档
myWriter.WriteStartDocument(); //write the comment
myWriter.WriteComment("这是一个子查询例子");
for(int i=1;i<ListBox1.Items.Count;i++)
{
myWriter.WriteStartElement("AccountNo","");
string b=ListBox1.Items[0].Text;
myWriter.WriteString(b);
myWriter.WriteEndElement();
}
myWriter.WriteEndDocument();
myWriter.Flush();
myWriter.Close(); Response.Redirect(Server.MapPath("../WebApplication1/XMLData/new.xml"));
}
我的问题时这样会发生错误,提示为:处于状态 Epilog 的标记 StartElement 将导致无效的 XML 文档。错误发生在 myWriter.WriteStartElement("AccountNo","");
请问这是什么错误,如何解决?还有什么办法适用XPath来查询,从而将自查询结果显示在叶面上的,最好使用DataGrid这些控件?
这循环外要写个根元素吧。
//write the comment
myWriter.WriteComment("这是一个子查询例子");
for(int i=1;i<ListBox1.Items.Count;i++)
{
myWriter.WriteStartElement("AccountNo"); //这里改了
string b=ListBox1.Items[0].Text;
myWriter.WriteString(b);
myWriter.WriteEndElement();
}
myWriter.WriteEndElement();
myWriter.WriteEndDocument();
...
doc.Load(Server.MapPath("../WebApplication1/XMLData/Bank.xml"));
XmlNodeList nodes=doc.SelectNodes("Bank/Account[child::Name='AA']/AccountNo");DataGrid1.DataSource=nodes;
DataGrid1.DataBind();
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Bank.xsl -->
<xsl:param name="Name"/>
<xsl:template match="/">
<Table border="0" width="100%">
<tr>
<td>AccountNo</td>
<td>Name</td>
<td>Balance</td>
</tr>
<xsl:apply-templates select="Bank"/>
</Table>
</xsl:template>
<xsl:template match="Bank">
<xsl:for-each select="/Account">
<xsl:if test="//Name=$Name">
<tr>
<td><xsl:value-of select="//AccountNo"/></td>
<td><xsl:value-of select="//Name"/></td>
<td><xsl:value-of select="//Balance"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet><%@ Page language="c#" Codebehind="TransformBankXml.aspx.cs" AutoEventWireup="false" Inherits="tempAspx.TransformBankXml" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>TransformBankXml</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:Label id="Label1" runat="server" Width="100px">UserName</asp:Label>
<asp:TextBox id="TextBox1" runat="server"></asp:TextBox>
<asp:Button id="Button1" runat="server" Text="Button"></asp:Button>
</form>
</body>
</HTML>
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;namespace tempAspx
{
/// <summary>
/// TransformBankXml 的摘要说明。
/// </summary>
public class TransformBankXml : System.Web.UI.Page
{
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button1;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
} #region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load); }
#endregion private void Button1_Click(object sender, System.EventArgs e)
{
try
{
string UserName = TextBox1.Text;
XPathDocument bankXml = new XPathDocument(HttpContext.Current.Server.MapPath("Bank.xml"));
XslTransform xt = new XslTransform();
xt.Load(HttpContext.Current.Server.MapPath("Bank.xsl"));
XsltArgumentList _Args = null;
if(UserName != String.Empty)
{
_Args = new XsltArgumentList();
_Args.AddParam("Name","",UserName);
}
XmlTextWriter writer = new XmlTextWriter(Server.MapPath("output.xml"),null);
//xt.Transform(bankXml,_Args,Response.Output);
xt.Transform(bankXml,_Args,writer,null);
writer.Close();
HttpContext.Current.Response.Redirect(HttpContext.Current.Server.MapPath("output.xml"));
}
catch(Exception ee)
{
Response.Write(ee.Message);
}
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Bank.xsl -->
<xsl:param name="Name"/>
<xsl:template match="/">
<Table border="0" width="100%">
<tr>
<td>AccountNo</td>
<td>Name</td>
<td>Balance</td>
</tr>
<xsl:apply-templates select="Bank"/>
</Table>
</xsl:template>
<xsl:template match="Bank">
<xsl:for-each select="Account">
<xsl:if test="Name=$Name">
<tr>
<td><xsl:value-of select="AccountNo"/></td>
<td><xsl:value-of select="Name"/></td>
<td><xsl:value-of select="Balance"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>