GridView绑定到XML

4

我正在尝试制作一个简单的网格视图,该视图绑定到一个简单的xml文档,但由于某些原因我一直收到错误消息:

GridView ID为“GridView1”的数据源没有任何属性或属性可生成列。请确保您的数据源具有内容。

代码

<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 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>

也许是我的xpath有误还是我在这里犯了一些基本错误?
4个回答

7
有几种方法可以使其工作:
  1. 使用Brian的解决方案,将XML重写为使用属性而不是子节点。
  2. 使用XSLT转换动态将子节点转换为属性。请参阅此SO问题以获取可以执行该操作的XSLT。
  3. 将XML数据加载到DataSet中,该DataSet在内部进行此转换。
这里是如何执行#3的示例:
DataSet ds = new DataSet();
ds.ReadXml(MapPath("~/App_Data/mydata.xml"));
GridView1.DataSource = ds;
GridView1.DataBind();

这种方法的局限性在于,您无法像使用数据源控件一样自动绑定数据。但是,由于XmlDataSource控件本身是只读的,因此这并不一定是一个严重的限制。

3

XmlDataSource使用属性而不是子实体。您需要执行以下操作:

<node id="1096" name="About Us" ../>

不要使用子元素。很遗憾,只能这样做;我真的希望可以使用替代方法;我更喜欢那种方式。


我不明白你刚才说的话。 - Joseph Yaduvanshi
啊,它把我的示例转换成了HTML标签;对此我感到很抱歉。它不理解<node><id></id>语法;它期望像<node id="1" name="test" desc="that" />这样的属性。 - Brian Mains

0

动态数据绑定到XML文档

如果您的Xml结构包含更多信息,您将能够更轻松地迭代整个结构,因为更容易识别您要查找的确切节点。

我们有一个Web服务,返回行/列结构的XML(类似于上面的数据示例)

为了提高速度,我复制/粘贴了我们的解决方案,但是您应该能够理解并能够修改它以执行您的操作。

<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> 

以下是 C# 的实现:

  • 我们将列名取出以传递到 Gridviews.Datakey 名称数组中的数据
  • 我们循环遍历行,并在沿途添加每一行到数据集中
  • 我们将 gridviews datasounce 设置为数据集
  • 我们 bind()

以下是样例代码,包含一些 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;

0
尝试将XPath更改为:
看起来像 XPath="data/node"

没有帮助。我尝试了不同的路径,甚至不同的XML文件。 - jpkeisala
1
要使用元素中的数据,您需要执行以下操作来从 XML 中提取 ID。Brian 在下面提到 XmlDataSouce 使用属性是一个很好的观点。 " /> - Sean Barlow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接