473,382 Members | 1,349 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Restructure XML

I would like to restructure my xml with a generic style sheet to perform the following. I want to be able to inspect a group of nodes then place them into a collection node if there are more than one at the same level with the same name. This should occur as well if sub-levels have consecutive node names. Is this possible? I have worked on it for a while and have not come up with a method to generically do this. If anyone has any thoughts or ideas I'm listening.

SOURCE
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
<shift>day</shift>
<shift>night</shift>
</root>

Now I run through the generic stylesheet and what I want to now have is:

DESTINATION
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<collection>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
</collection>
<collection>
<shift>day</shift>
<shift>night</shift>
</collection>
</root>

Thanks,

Matt

Nov 12 '05 #1
5 1310
I'm not sure why you would bother. You could easily get a list of all the
people nodes or all the shift nodes by using the .SelectNodes method and
work with them as needed. What would putting them under a parent node
call collection do for you?

I'm guessing you don't have a lot of familiarity with XPath queries.
Perhaps you should take a look at this set of basic syntax samples.
It is a COM sample, not .NET, but the XPath queries are still applicable.

http://www.eggheadcafe.com/articles/20030627d.asp

But, to answer your question specifically, yes you can certainly do
what you are asking.

--
2004 and 2005 Microsoft MVP C#
Robbe Morris
http://www.robbemorris.com
http://www.masterado.net

"Matt" <md*****@sorvive.DONT-SEND-SPAM.com> wrote in message news:Om**************@tk2msftngp13.phx.gbl...
I would like to restructure my xml with a generic style sheet to perform the following. I want to be able to inspect a group of nodes then place them into a collection node if there are more than one at the same level with the same name. This should occur as well if sub-levels have consecutive node names. Is this possible? I have worked on it for a while and have not come up with a method to generically do this. If anyone has any thoughts or ideas I'm listening.

SOURCE
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
<shift>day</shift>
<shift>night</shift>
</root>

Now I run through the generic stylesheet and what I want to now have is:

DESTINATION
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<collection>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
</collection>
<collection>
<shift>day</shift>
<shift>night</shift>
</collection>
</root>

Thanks,

Matt

Nov 12 '05 #2
Robbe,

I am working with documents that have over 425 nodes in them and I do this
with more than 3000 customers. I am trying to find a way to work with their
XML documents more generically in our processes.

I have actually been working with XML for about 7 years now and that is why
I was probably making the sample XML too generic and simple. I understand
XPath quite well and know XQuery as well. I am trying to figure out how to
reformat our customers XML into a generic form to simply our processes. I
could easily do this if I received the same data from all 3000 customers but
I do not.

If you would like to work with one of my 100mb XML documents I would gladly
send it to you if you would like to see something much more complex. Let me
know if you would like to help out.

Matt
"Robbe Morris [C# MVP]" <in**@eggheadcafe.com> wrote in message
news:eb*************@TK2MSFTNGP15.phx.gbl...
I'm not sure why you would bother. You could easily get a list of all the
people nodes or all the shift nodes by using the .SelectNodes method and
work with them as needed. What would putting them under a parent node
call collection do for you?

I'm guessing you don't have a lot of familiarity with XPath queries.
Perhaps you should take a look at this set of basic syntax samples.
It is a COM sample, not .NET, but the XPath queries are still applicable.

http://www.eggheadcafe.com/articles/20030627d.asp

But, to answer your question specifically, yes you can certainly do
what you are asking.

--
2004 and 2005 Microsoft MVP C#
Robbe Morris
http://www.robbemorris.com
http://www.masterado.net

"Matt" <md*****@sorvive.DONT-SEND-SPAM.com> wrote in message
news:Om**************@tk2msftngp13.phx.gbl...
I would like to restructure my xml with a generic style sheet to perform
the following. I want to be able to inspect a group of nodes then place
them into a collection node if there are more than one at the same level
with the same name. This should occur as well if sub-levels have
consecutive node names. Is this possible? I have worked on it for a while
and have not come up with a method to generically do this. If anyone has
any thoughts or ideas I'm listening.

SOURCE
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
<shift>day</shift>
<shift>night</shift>
</root>

Now I run through the generic stylesheet and what I want to now have is:

DESTINATION
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<collection>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
</collection>
<collection>
<shift>day</shift>
<shift>night</shift>
</collection>
</root>

Thanks,

Matt
Nov 12 '05 #3
Matt wrote:
I would like to restructure my xml with a generic style sheet to perform
the following. I want to be able to inspect a group of nodes then place
them into a collection node if there are more than one at the same level
with the same name. This should occur as well if sub-levels have
consecutive node names. Is this possible? I have worked on it for a
while and have not come up with a method to generically do this. If
anyone has any thoughts or ideas I'm listening.

_*SOURCE*_
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
<shift>day</shift>
<shift>night</shift>
</root>

Now I run through the generic stylesheet and what I want to now have is:

*_DESTINATION_*
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<collection>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/>
</collection>
<collection>
<shift>day</shift>
<shift>night</shift>
</collection>
</root>


You could try something like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="nameKey" match="*" use="concat(name(), '||',
generate-id(..))"/>
<xsl:template match="/|*" priority="1">
<xsl:for-each select="*[generate-id() =
generate-id(key('nameKey', concat(name(), '||', generate-id(..))))]">
<xsl:variable name="namesake" select="key('nameKey',
concat(name(), '||', generate-id(..)))"/>
<xsl:choose>
<xsl:when test="count($namesake) = 1">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="."/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<collection>
<xsl:for-each select="$namesake">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="."/>
</xsl:copy>
</xsl:for-each>
</collection>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

PS. NOt optimized - just an idea.

--
Oleg Tkachenko [XML MVP, MCP]
http://blog.tkachenko.com
Nov 12 '05 #4
Oleg,

You kill me with how quickly you can create a solution! I don't know what I
would do without your suggestions. Now to only figure out how it works and
why.

Thanks again, this is exactly the type of thing I was looking for.

Matt
"Oleg Tkachenko [MVP]" <oleg@NO!SPAM!PLEASEtkachenko.com> wrote in message
news:ue**************@TK2MSFTNGP10.phx.gbl...
Matt wrote:
I would like to restructure my xml with a generic style sheet to perform
the following. I want to be able to inspect a group of nodes then place
them into a collection node if there are more than one at the same level
with the same name. This should occur as well if sub-levels have
consecutive node names. Is this possible? I have worked on it for a
while and have not come up with a method to generically do this. If
anyone has any thoughts or ideas I'm listening. _*SOURCE*_
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/> <shift>day</shift>
<shift>night</shift> </root>
Now I run through the generic stylesheet and what I want to now have is:
*_DESTINATION_*
<root>
<job>
<janitor/>
<programmer/>
<administrator/>
</job>
<collection>
<person name="Matt"/>
<person name="Bob"/>
<person name="Larry"/> </collection>
<collection>
<shift>day</shift>
<shift>night</shift> </collection>
</root>


You could try something like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="nameKey" match="*" use="concat(name(), '||',
generate-id(..))"/>
<xsl:template match="/|*" priority="1">
<xsl:for-each select="*[generate-id() = generate-id(key('nameKey',
concat(name(), '||', generate-id(..))))]">
<xsl:variable name="namesake" select="key('nameKey',
concat(name(), '||', generate-id(..)))"/>
<xsl:choose>
<xsl:when test="count($namesake) = 1">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="."/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<collection>
<xsl:for-each select="$namesake">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="."/>
</xsl:copy>
</xsl:for-each>
</collection>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

PS. NOt optimized - just an idea.

--
Oleg Tkachenko [XML MVP, MCP]
http://blog.tkachenko.com

Nov 12 '05 #5
Matt wrote:
Now to only figure out how it works and why.


It's basically classical Muenchian grouping. For each element
recursively I group children by name and if there is more than one child
with the same name, I wrap them in <collection>. The identity transform
template at the end is for other content such as text, comments and PIs
to be copied as is.

--
Oleg Tkachenko [XML MVP, MCP]
http://blog.tkachenko.com
Nov 12 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Laphan | last post by:
Hi All Wonder if you could help, I have a bog standard table called STOCKPRICES that has served me well for a while, but now I need to change the structure of it and because a number of users...
8
by: John Hardy | last post by:
I have the following SQL code in my databse as a querry. SELECT Sheet1.ID, Sheet1.Field6, Sheet2.ID, Sheet2.Field6 FROM Sheet1 INNER JOIN Sheet2 ON Sheet1.ID = Sheet2.ID WHERE (((!)<>! Or (!)...
2
by: HJ | last post by:
Hi all, I am looking at a problem we encountered with replication. Our front-end and back-end are Microsoft Access 2000. We have a design master at the server and replicas at five notebooks. The...
6
by: strvariant | last post by:
Our company contracted with an outside consultant over a year ago to build a complex database application. The end product was put into production over nine months ago. Since then it has been...
109
by: Neo | last post by:
Hi Folks,http://www.abarnett.demon.co.uk/tutorial.html#FASTFOR Page states:for( i=0; i<10; i++){ ... }i loops through the values 0,1,2,3,4,5,6,7,8,9 If you don't care about the order of the loop...
5
by: Rajat Tandon | last post by:
Hello Everybody, Please guide me so that I can fulfill this challenging assisnment ... I have been asked to "Restructure a Windows application" from scratch in 2 months. The existing...
0
by: Gerard Flanagan | last post by:
For anyone interested, here's a blog entry I've added over at the Tutorial Wiki: ---------------------------------------- As mentioned by effbot in the previous post I've put together a...
2
by: Takeadoe | last post by:
Dear NG, In an earlier post to the group, I was trying to find and easy way to calculate %change estimates between years for a group of variables. My data looks like this: Year County VarA...
6
by: tropos | last post by:
For my sins, I'm maintaining some old C code which is migrated to C++. Dozens of lines of it looks like this: char *cfd_THE_ts_result_sql= "select TRADE_DATE , VALUE , " " from (" " select...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.