Create hierarchy from "flat" XML using DataSet/DataView?

G

Guest

Hi,
I have a "flat" XML file that I want to convert to a hierarchy as listed on
the bottom.
The XSLT I tried works fine in the XSelerator too but is slow when using
XslTransform().

Is there a way to do this using a DataSet or DataView? I've looked into
DataRelations but that works with 2 or more datatables. I only have the one
below

FROM...

<NewDataSet>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>20</CodeId>
<CodeName>AAAA</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>21</CodeId>
<CodeName>BBBB</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>22</CodeId>
<CodeName>CCCCCC</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>23</CodeId>
<CodeName>DDDDD</CodeName>
</row>
</NewDataSet

TO...

<?xml version="1.0" encoding="UTF-16"?>
<companycodelist>
<company>
<companyid>676708</companyid>
<companyname>Acme Corporation</companyname>
<codes>
<code id="20" name="AAAA"></code>
<code id="21" name="BBBB"></code>
<code id="22" name="CCCCCC"></code>
<code id="23" name="DDDDD"></code>
</codes>
</company>
</companycodelist>
 
S

Sahil Malik

Don't know if dataset is any better performing than XSLT, because well - it
isn't meant for XSLT - but you can try the below and test run it yourself.
Secondly - DataSet.WriteXml will not convert elements to attributes as you
want below.
Thirdly - You can't selectively not write out columns using a dataset only
without overriding a whole bunch of things.

Anyway, you can get close to what you are trying to acheive by using code
that looks like this ---

DataSet ds = new DataSet() ;
ds.ReadXml("C:\\1.xml") ; // This was your XML
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("CompanyID"));
dt.Columns.Add(new DataColumn("ComanyName"));
DataRow dr = dt.NewRow();
dr[0] = "676708";
dr[1] = "Acme Corporation";
dt.Rows.Add(dr);
ds.Tables.Add(dt);
ds.Relations.Add(new
DataRelation("myrel",ds.Tables[1].Columns[0], ds.Tables[0].Columns[0])) ;
ds.Relations[0].Nested = true;
ds.WriteXml("C:\\2.xml") ;

And well - the nested using datarelation in one table - it can be done -
using a self referential constraint -- but not on the same column. Consider
this - new datarelation ("abc", column1, column1) <-- No logical sense.

Last bit of Info - XSLT performance is being boosted by 400% in .NET 2.0.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
G

Guest

Sahil,

Thanks. Since you mention XSTL performance. I'll expand on what I'm doing.

Since the XML is coming from my dataset (that is loaded from a webservice),
I wanted to re-shape or normalize it as I mentioned using XSLT/grouping. The
code to call the transform...

XmlDataDocument xmldd = new XmlDataDocument(dst);
XslTransform transform = new XslTransform();
transform.Load(Server.MapPath(XsltDocumentName));
XmlReader reader = transform.Transform(xmldd, null, new XmlUrlResolver());
XmlDocument xmldoc2 = new XmlDocument();
xmldoc2.Load(reader);

Is this type of "grouping" transformation known to be slow in .NET?

Dave

Sahil Malik said:
Don't know if dataset is any better performing than XSLT, because well - it
isn't meant for XSLT - but you can try the below and test run it yourself.
Secondly - DataSet.WriteXml will not convert elements to attributes as you
want below.
Thirdly - You can't selectively not write out columns using a dataset only
without overriding a whole bunch of things.

Anyway, you can get close to what you are trying to acheive by using code
that looks like this ---

DataSet ds = new DataSet() ;
ds.ReadXml("C:\\1.xml") ; // This was your XML
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("CompanyID"));
dt.Columns.Add(new DataColumn("ComanyName"));
DataRow dr = dt.NewRow();
dr[0] = "676708";
dr[1] = "Acme Corporation";
dt.Rows.Add(dr);
ds.Tables.Add(dt);
ds.Relations.Add(new
DataRelation("myrel",ds.Tables[1].Columns[0], ds.Tables[0].Columns[0])) ;
ds.Relations[0].Nested = true;
ds.WriteXml("C:\\2.xml") ;

And well - the nested using datarelation in one table - it can be done -
using a self referential constraint -- but not on the same column. Consider
this - new datarelation ("abc", column1, column1) <-- No logical sense.

Last bit of Info - XSLT performance is being boosted by 400% in .NET 2.0.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik







Dave said:
Hi,
I have a "flat" XML file that I want to convert to a hierarchy as listed on
the bottom.
The XSLT I tried works fine in the XSelerator too but is slow when using
XslTransform().

Is there a way to do this using a DataSet or DataView? I've looked into
DataRelations but that works with 2 or more datatables. I only have the one
below

FROM...

<NewDataSet>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>20</CodeId>
<CodeName>AAAA</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>21</CodeId>
<CodeName>BBBB</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>22</CodeId>
<CodeName>CCCCCC</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>23</CodeId>
<CodeName>DDDDD</CodeName>
</row>
</NewDataSet

TO...

<?xml version="1.0" encoding="UTF-16"?>
<companycodelist>
<company>
<companyid>676708</companyid>
<companyname>Acme Corporation</companyname>
<codes>
<code id="20" name="AAAA"></code>
<code id="21" name="BBBB"></code>
<code id="22" name="CCCCCC"></code>
<code id="23" name="DDDDD"></code>
</codes>
</company>
</companycodelist>
 
S

Sahil Malik

Dave,

So I have heard, but never confirmed, xslt transforms are slow in .NET in
general as compared to other platforms. But again I have never confirmed.
The kind of transform you mention below - is exactly the kind that has been
sped up by 400% as per an MSDN article I read long back. So lets put it this
way - if you go the route below, you will get a 4 times perf. boost
(hopefully).

Now that article was way back - and again, I didn't write code to confirm
it, but I am pretty certain of what I read.

PS: Incidentally, a quick search on google revealed my source of
information -
http://msdn.microsoft.com/msdnmag/issues/04/02/XMLFiles/default.aspx

It reads ----

"System.Xml in "Whidbey"

The new version of Visual Studio® and the .NET Framework, code-named
"Whidbey," will include new System.Xml features. Most of the System.Xml
improvements in Whidbey will be centered on performance or usability. In
terms of performance, both XmlTextReader and XmlTextWriter are twice as fast
as they were in version 1.1 implementations. XML Schema validation is a more
modest 20 percent faster while the XSLT transformation engine blows away
previous versions with a whopping 400 percent performance increase (Figure
2) comparing the time it takes to perform various tasks. These improvements
are highly anticipated since performance speeds became one of the most
common criticisms of the .NET Framework version 1.1."

So in short - the transform below sucks in 1.1, but is gonna kick a33 in
2.0.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik


Dave said:
Sahil,

Thanks. Since you mention XSTL performance. I'll expand on what I'm
doing.

Since the XML is coming from my dataset (that is loaded from a
webservice),
I wanted to re-shape or normalize it as I mentioned using XSLT/grouping.
The
code to call the transform...

XmlDataDocument xmldd = new XmlDataDocument(dst);
XslTransform transform = new XslTransform();
transform.Load(Server.MapPath(XsltDocumentName));
XmlReader reader = transform.Transform(xmldd, null, new XmlUrlResolver());
XmlDocument xmldoc2 = new XmlDocument();
xmldoc2.Load(reader);

Is this type of "grouping" transformation known to be slow in .NET?

Dave

Sahil Malik said:
Don't know if dataset is any better performing than XSLT, because well -
it
isn't meant for XSLT - but you can try the below and test run it
yourself.
Secondly - DataSet.WriteXml will not convert elements to attributes as
you
want below.
Thirdly - You can't selectively not write out columns using a dataset
only
without overriding a whole bunch of things.

Anyway, you can get close to what you are trying to acheive by using code
that looks like this ---

DataSet ds = new DataSet() ;
ds.ReadXml("C:\\1.xml") ; // This was your XML
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("CompanyID"));
dt.Columns.Add(new DataColumn("ComanyName"));
DataRow dr = dt.NewRow();
dr[0] = "676708";
dr[1] = "Acme Corporation";
dt.Rows.Add(dr);
ds.Tables.Add(dt);
ds.Relations.Add(new
DataRelation("myrel",ds.Tables[1].Columns[0], ds.Tables[0].Columns[0])) ;
ds.Relations[0].Nested = true;
ds.WriteXml("C:\\2.xml") ;

And well - the nested using datarelation in one table - it can be done -
using a self referential constraint -- but not on the same column.
Consider
this - new datarelation ("abc", column1, column1) <-- No logical sense.

Last bit of Info - XSLT performance is being boosted by 400% in .NET 2.0.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik







Dave said:
Hi,
I have a "flat" XML file that I want to convert to a hierarchy as
listed on
the bottom.
The XSLT I tried works fine in the XSelerator too but is slow when
using
XslTransform().

Is there a way to do this using a DataSet or DataView? I've looked
into
DataRelations but that works with 2 or more datatables. I only have
the one
below

FROM...

<NewDataSet>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>20</CodeId>
<CodeName>AAAA</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>21</CodeId>
<CodeName>BBBB</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>22</CodeId>
<CodeName>CCCCCC</CodeName>
</row>
<row>
<CompanyId>676708</CompanyId>
<CompanyName>Acme Corporation</CompanyName>
<CodeId>23</CodeId>
<CodeName>DDDDD</CodeName>
</row>
</NewDataSet

TO...

<?xml version="1.0" encoding="UTF-16"?>
<companycodelist>
<company>
<companyid>676708</companyid>
<companyname>Acme Corporation</companyname>
<codes>
<code id="20" name="AAAA"></code>
<code id="21" name="BBBB"></code>
<code id="22" name="CCCCCC"></code>
<code id="23" name="DDDDD"></code>
</codes>
</company>
</companycodelist>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top