using xsd and datasets with XmlDataDocument

  • Thread starter Thread starter kevin_Eld
  • Start date Start date
K

kevin_Eld

I have the following xml:

<message>
<envelope>
<body key="" value="" />
</envelope>
</message>

I have associated an xsd to this xml in order to use the
XmlDataDocument and give me the
possibility to access the data through a dataset in the manner below
specified:

DataSet ds = XmlDataDocument.DataSet;

When I try to add an element of type "body" to this xml file, this tag
is added to the node
"message" while I want to add it to the node "envelope".
Here is the code which I use to do this task:

DataRow dr = ds.Tables["body"].NewRow();
dr["key"]=126;
dr["value"]="example";
ds.Tables["body"].Rows.Add(dr);

and here is the resulting xml:
<message>
<envelope>
<body key="" value="" />
</envelope>
<body key="126" value="example" />
</message>

while I want the following result:
<message>
<envelope>
<body key="" value="" />
<body key="126" value="example" />
</envelope>
</message>

Last but not least when I try to get the attribute values of the node
inserted in the xml by
the previous code I don't have any problem even if the xsd doesn't
allow a "body" tag out of
the "envelope" tag. For example:

foreach(DataRow row in ds.Tables["body"].Rows )
{
if (row[0].ToString() == "126")
{
myVariable = row[1].ToString();
break;
}
}


How can I avoid to append the node inserted by code to the
root node using the dataset and its related classes ? How can I insert
the new node
correctly inside the envelope element (always using datasets) ?

Every suggestion will be appreciate,
thanks in advance
 
Hi Kevin,
The trick is in knowing what the data set is doing under the covers when it
reads in nested elements like you are using. The data set will treat the
root element as the data set name, then treats each first level element as a
table. If it finds nested elements that have child nodes themselves
(attributes or child elements), it treats them as another table and sets up
a parent-child relation and foriegn key corresponding to that nested
relation.

In order to pull that off, it has to have a foreign key field to base the
relation on. In the case of your data, it fabricates a column in each of the
envelope and body tables, named envelope_Id and uses that to set up the
relation.

Since there is only one envelope element in the sample you gave, the
envelope_Id for that table's single row is 0, so what you would need to do
to make a new body element be nested correctly is the following:

DataRow dr = ds.Tables["body"].NewRow();

dr["key"]=126;

dr["value"]="example";

dr["envelope_Id"] = 0;

ds.Tables["body"].Rows.Add(dr);

By setting that additional FK field to the appropriate value, the new body
element will be properly nested under the envelope element.

Hope that helps.
Brian Noyes
MVP, Visual Developer - ASP/ASP.NET
IDesign, Inc. www.idesign.net

kevin_Eld said:
I have the following xml:

<message>
<envelope>
<body key="" value="" />
</envelope>
</message>

I have associated an xsd to this xml in order to use the
XmlDataDocument and give me the
possibility to access the data through a dataset in the manner below
specified:

DataSet ds = XmlDataDocument.DataSet;

When I try to add an element of type "body" to this xml file, this tag
is added to the node
"message" while I want to add it to the node "envelope".
Here is the code which I use to do this task:

DataRow dr = ds.Tables["body"].NewRow();
dr["key"]=126;
dr["value"]="example";
ds.Tables["body"].Rows.Add(dr);

and here is the resulting xml:
<message>
<envelope>
<body key="" value="" />
</envelope>
<body key="126" value="example" />
</message>

while I want the following result:
<message>
<envelope>
<body key="" value="" />
<body key="126" value="example" />
</envelope>
</message>

Last but not least when I try to get the attribute values of the node
inserted in the xml by
the previous code I don't have any problem even if the xsd doesn't
allow a "body" tag out of
the "envelope" tag. For example:

foreach(DataRow row in ds.Tables["body"].Rows )
{
if (row[0].ToString() == "126")
{
myVariable = row[1].ToString();
break;
}
}


How can I avoid to append the node inserted by code to the
root node using the dataset and its related classes ? How can I insert
the new node
correctly inside the envelope element (always using datasets) ?

Every suggestion will be appreciate,
thanks in advance
 
Back
Top