C# Gridview 绑定到 XML
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1988813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Gridview binding to XML
提问by jpkeisala
I am trying to make a simple grid view that is binded to a simple xml document but I must be missing something since I am keep getting error message:
我正在尝试制作一个简单的网格视图,该视图绑定到一个简单的 xml 文档,但我必须遗漏一些东西,因为我不断收到错误消息:
The data source for GridView with id 'GridView1' did not have any properties or attributes from which to generate columns. Ensure that your data source has content.
ID 为“GridView1”的 GridView 的数据源没有任何属性或属性可用于生成列。确保您的数据源具有内容。
Code
代码
<asp:GridView ID="GridView1" runat="server" DataSourceID="XmlDataSource1">
<Columns>
<asp:BoundField DataField="id" HeaderText="ID" SortExpression="id" />
</Columns>
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server"
DataFile="Notifications.xml" XPath="/data/node"></asp:XmlDataSource>
XML
XML
<?xml version="1.0" encoding="utf-8" ?>
<data>
<node>
<id>1096</id>
<name>About Us</name>
<date>21/12/2009 17:03:43</date>
<user id="1">writer</user>
</node>
<node>
<id>1099</id>
<name>News</name>
<date>21/12/2009 17:03:47</date>
<user id="1">writer</user>
</node>
<node>
<id>1098</id>
<name>Another page</name>
<date>21/12/2009 17:03:52</date>
<user id="1">writer</user>
</node>
</data>
Is it perhaps my xpath that is wrong or am I making something fundamentally wrong here?
也许是我的 xpath 出错了,还是我在这里做了一些根本性的错误?
采纳答案by Eilon
There are a number of ways to get this to work:
有多种方法可以使其发挥作用:
- Use Brian's solution, which is to rewrite the XML to use attributes instead of sub-nodes.
- Use an XSLT transform to dynamically convert the child nodes to attributes. See this SO questionfor an XSLT that can perform that operation.
- Load the XML data into a DataSet, which internally does this conversion.
- 使用 Brian 的解决方案,即重写 XML 以使用属性而不是子节点。
- 使用 XSLT 转换将子节点动态转换为属性。有关可以执行该操作的 XSLT,请参阅此 SO 问题。
- 将 XML 数据加载到 DataSet 中,该数据集在内部执行此转换。
Here's an example of how to do #3:
以下是如何执行 #3 的示例:
DataSet ds = new DataSet();
ds.ReadXml(MapPath("~/App_Data/mydata.xml"));
GridView1.DataSource = ds;
GridView1.DataBind();
The limitation of this last approach is that you don't get automatic databinding as you would with a data source control. However, since the XmlDataSource is a read-only control anyway, that's not necessarily a serious limitation.
最后一种方法的局限性在于,您无法像使用数据源控件那样获得自动数据绑定。但是,由于 XmlDataSource 无论如何都是只读控件,因此这不一定是一个严重的限制。
回答by Sean Barlow
try changeing the xpath to
尝试将 xpath 更改为
look like XPath="data/node"
看起来像 XPath="data/node"
回答by Brian Mains
XmlDataSource works with attributes, not child entities. You need to do:
XmlDataSource 使用属性,而不是子实体。你需要做:
<node id="1096" name="About Us" ../>
Instead of using child elements. Unfortunately it is this way; I really wish it would work with the alternative; I like that approach much better.
而不是使用子元素。不幸的是,它是这样的;我真的希望它可以与替代方案一起使用;我更喜欢这种方法。
回答by Aaron Hopkins
Dynamic Databind to XML Document
动态数据绑定到 XML 文档
If your Xml is structured with more info, you will be able to iterate over the structure with more ease, as its easier to identify the exact node your looking for.
如果您的 Xml 包含更多信息,您将能够更轻松地遍历该结构,因为它更容易识别您要查找的确切节点。
We have a web service that returns XML in a row/column structure (similar to your data example above)
我们有一个以行/列结构返回 XML 的 Web 服务(类似于上面的数据示例)
For speed Ive copy/pasted our solution, but you should get the gist and be able to hack it to do your thing.
为了速度,我复制/粘贴了我们的解决方案,但您应该了解要点并能够破解它来做您的事情。
<response xmlns="">
<method name="ExecuteMethod">
<message>Query Successful</message>
<summary success="true" rowcount="2" />
<row>
<column name="ID"><![CDATA[SomeData]]></column>
<column name="NHS_NO"><![CDATA[SomeData]]></column>
<column name="HOSPITALNUMBER"><![CDATA[SomeData]]></column>
<column name="SURNAME"><![CDATA[SomeData]]></column>
<column name="FIRST_FORENAME"><![CDATA[SomeData]]></column>
<column name="TITLE"><![CDATA[SomeData]]></column>
<column name="SEX"><![CDATA[SomeData]]></column>
<column name="DOB">SomeData</column>
<column name="ADDRESS"><![CDATA[SomeData]]></column>
<column name="POSTCODE"><![CDATA[SomeData]]></column>
<column name="DOD" />
</row>
<row>
<column name="ID"><![CDATA[SomeData]]></column>
<column name="NHS_NO"><![CDATA[SomeData]]></column>
<column name="HOSPITALNUMBER"><![CDATA[SomeData]]></column>
<column name="SURNAME"><![CDATA[SomeData]]></column>
<column name="FIRST_FORENAME"><![CDATA[SomeData]]></column>
<column name="TITLE"><![CDATA[SomeData]]></column>
<column name="SEX"><![CDATA[SomeData]]></column>
<column name="DOB">SomeData</column>
<column name="ADDRESS"><![CDATA[SomeData]]></column>
<column name="POSTCODE"><![CDATA[SomeData]]></column>
<column name="DOD" />
</row>
</method>
</response>
Here's the c# implementation
这是c#实现
- we get the Column names out to pass to the data in to the Gridviews.Datakey names array
- we loop over the rows, adding each row to the dataset as we go along
- we set the gridviews datasounce to the dataset
- we bind()
- 我们获取列名称以将数据传递给 Gridviews.Datakey 名称数组
- 我们遍历行,将每一行添加到数据集中
- 我们将 gridviews datasounce 设置为数据集
- 我们绑定()
There's a bit of css and the control instance for your ease of copy/paste in the example below.
在下面的示例中,有一些 css 和控件实例,便于您复制/粘贴。
//In Code In Front...
Table.DataGridView{float:left; width:100%;}
Table.DataGridView tr{}
Table.DataGridView th{ background-color:Gray; font-weight:bold; color:White;}
Table.DataGridView td{ background-color:White; color:Black; font-weight:normal;}
<asp:GridView ID="DataGridView" runat="server" CssClass="DataGridView" GridLines="Both" Visible="false" />
//In Code Behind...
XmlNode myXmlNodeObject = myXmlDocService.GetData(_xmlDataString);
//Bind To GridView
//Create a DataSet To Bind To
DataSet ds = new DataSet();
ds.Tables.Add("XmlDataSet");
//Get Column Names as String Array
XmlDocument XMLDoc = new XmlDocument();
XMLDoc.LoadXml("<result>" +myXmlNodeObject.ChildNodes.Item(0).ChildNodes.Item(2).ParentNode.InnerXml + "</result>"); //Get Row/Columns
int colCount = myXmlNodeObject.ChildNodes.Item(0).ChildNodes.Item(2).SelectNodes("column").Count;
string[] ColumnNameArray = new string[colCount];
int iterator = 0;
foreach(XmlNode node in myXmlNodeObject.ChildNodes.Item(0).ChildNodes.Item(2).SelectNodes("column"))
{
ColumnNameArray.SetValue(node.Attributes["name"].Value ,iterator);
ds.Tables["XmlDataSet"].Columns.Add(node.Attributes["name"].Value); //Create individual columns in the dataset
iterator++;
}
//Get Data Row By Row to populate the DataSet.Rows
foreach(XmlNode RowNode in XMLDoc.ChildNodes.Item(0).SelectNodes("row"))
{
string[] rowArray = new string[colCount];
int iterator2 = 0;
foreach(XmlNode ColumnNode in RowNode.ChildNodes)
{
rowArray.SetValue(ColumnNode.InnerText, iterator2);
iterator2++;
}
ds.Tables["XmlDataSet"].Rows.Add(rowArray);
}
DataGridView.DataSource = ds.Tables["XmlDataSet"];
DataGridView.DataKeyNames = ColumnNameArray;
DataGridView.DataBind();
DataGridView.Visible = true;