Solved

Two xml Documents to One!

Posted on 2002-03-08
15
201 Views
Last Modified: 2013-11-19
Hi,

I have an XML document that links to two further XML documents, I need to take the first and run a calculation from a value off the second, and from this produce a third file.

I am iterating through the first using an for-each loop, after opening the document with the document command, writing ourput as I go.

When I come to a point where the identifiying variable is, I am trying to then go into the second XML document to retrieve the data I need, this is where I am struggling.

I am under the impression that I have moved down the tree to the point in XML file 1, then I must go up the tree to the first XML document that links the two files to then enter the second linked document containing the data.

I can't see how I can get data betwwen the two documents.

If anyone understands this can they plz help!

Thanks in advance.
0
Comment
Question by:psilli1
  • 10
  • 4
15 Comments
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852346
you can do this via the xslt document function. What parser are you using? You would also have to probably use the node-set function as well.

Post your XML documents (small data sets please) and your expected XML output and also, your XSLT document (i need to know the logic you are using) and we are cooking!
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852402
By the way, the best approach is to use XSLT to do the transform.

You could use the appendChild() to append the two documents into the main tree and then run the transform. Trying to do what you are doing using DOM methods alone is a nightmare.
0
 
LVL 1

Author Comment

by:psilli1
ID: 6852471
Hi,

I am using Saxon parser, I seem to have got around the problem but I am not sure if it is a good way or not.  I have created two parameters at the top of the XSLT, one for each of the filenames, now in the main templates of the XSLT i can simply reference which document I need.  It seems to work ok at the moment.

I am very interested though in how the node-set function is used.  I am assuming that it can be used to create a resultant node-set, which can then be parsed to obtain the data.

This is the main xml document, that links the further two together!
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Update SYSTEM "blah.DTD">
<?xml-stylesheet href="blah.xsl" type="text/xsl"?>
<blah>
     <el1 filename="blah.xml"/>
     <el2 filename="blahblah.xml"/>
</blah>

One Data File
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE NFLDivisions SYSTEM "onedata.dtd">
<main>
     <area>
          <Name>North</Name>
          <Team>
               <TeamName>Manchester United</TeamName>
               <League>
                    <Goals>
                         <For>100</For>
                         <Against>94</Against>
                    </Goals>
                    <WLTBreakdown Performance="home">
                         <Won>1</Won>
                         <Lost>0</Lost>
                         <Tied>0</Tied>
                    </WLTBreakdown>
                    <WLTBreakdown Performance="away">
                         <Won>1</Won>
                         <Lost>0</Lost>
                         <Tied>0</Tied>
                    </WLTBreakdown>

.......etc.......


The second xml document contains games.
<Score>
  <Game>
    <Home>
      <Team>Manchester Utd</Team>
      <Result>3</Result>
    </Home>
    <Away>
      <Team>Manchester City</Team>
      <Result>31</Result>
    </Away>
  </Game>
....etc.....

I want to reporoduce the league table with the new results taken into consideration.

Thanks
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852486
>>
I am very interested though in how the node-set function is used.  I am assuming that it can be used
to create a resultant node-set, which can then be parsed to obtain the data.

<<
it is used to access a document/node-set created inside a variable
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852529
could you provide the structure of the league tables??
0
 
LVL 1

Author Comment

by:psilli1
ID: 6852537
The Structure is the first document!
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852563
version of Saxon??? 6.2.2??
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:psilli1
ID: 6852565
6.5.1
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852566
I shall make the presumption that you are using 6.5.1 and will use the node-set function as stated here:

node-set($fragment) When version="1.1", a result-tree-fragment is converted implicitly to a node-set if it is used in a context where a node-set is required. However, for portability with other XSLT 1.0 processors, it may be better to use the EXSLT node-set() function. The function takes a single argument that is a result tree fragment. Its function is to convert the result tree fragment to a node-set. The resulting node-set contains a single node, which is a root node (class DocumentInfo); below this are the actual nodes added to the result tree fragment, which may be element nodes, text nodes, or anything else. Note that a result tree fragment is not in general a well-formed document, for example there may be multiple element nodes or text nodes as children of the root.

http://saxon.sourceforge.net/saxon6.5.1/extensions.html#nodeset
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852725
Here is the XML Document, XSLT Document and the final output tested with Saxon 6.5.1


directive.xml
============================

<?xml version="1.0" encoding="iso-8859-1"?>
<document>
    <main filename="data.xml"/>
    <update filename="update.xml"/>
</document>

data.xml
=========
<?xml version="1.0" encoding="iso-8859-1"?>
<main>
<area>
<Name>North</Name>
<Team>
<TeamName>Manchester United</TeamName>
<League>
<Goals>
<For>100</For>
<Against>94</Against>
</Goals>
<WLTBreakdown Performance="home">
<Won>1</Won>
<Lost>0</Lost>
<Tied>0</Tied>
</WLTBreakdown>
<WLTBreakdown Performance="away">
<Won>1</Won>
<Lost>0</Lost>
<Tied>0</Tied>
</WLTBreakdown>
</League>
</Team>
<Team>
<TeamName>Manchester City</TeamName>
<League>
<Goals>
<For>50</For>
<Against>95</Against>
</Goals>
<WLTBreakdown Performance="home">
<Won>0</Won>
<Lost>0</Lost>
<Tied>1</Tied>
</WLTBreakdown>
<WLTBreakdown Performance="away">
<Won>0</Won>
<Lost>1</Lost>
<Tied>0</Tied>
</WLTBreakdown>            
</League>
</Team>
</area>
</main>

update.xml
==========
<?xml version="1.0" encoding="iso-8859-1"?>
<Score>
<Game>
<Home>
<Team>Manchester United</Team>
<Result>3</Result>
</Home>
<Away>
<Team>Manchester City</Team>
<Result>1</Result>
</Away>
</Game>
</Score>


saxon.xsl
=========
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:saxon="http://icl.com/saxon" exclude-result-prefixes="saxon">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes" />
<xsl:variable name="main" select="document(//main/@filename)/main" />
<xsl:variable name="update" select="document(//update/@filename)/score" />
<xsl:template match="/">
<xsl:apply-templates select="saxon:node-set($main)/node()" mode="update" />
</xsl:template>
<xsl:template match="@* | node()" mode="update">
<xsl:copy><xsl:apply-templates select="@* | node()" mode="update" /></xsl:copy>
</xsl:template>

<!--total goals for-->
<xsl:template match="Goals/For" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="for" select="sum(saxon:node-set($update)//Result[preceding-sibling::Team[1] = $team])" />
<For><xsl:value-of select=". + $for" /></For>
</xsl:template>

<!--total goals against-->
<xsl:template match="Goals/Against" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="home" select="sum(saxon:node-set($update)//Game[Away/Team[. = $team]]/Home/Result)" />
<xsl:variable name="away" select="sum(saxon:node-set($update)//Game[Home/Team[. = $team]]/Away/Result)" />
<Against><xsl:value-of select=". + $away + $home" /></Against>
</xsl:template>

<!--home details-->
<xsl:template match="WLTBreakdown[@Performance[. = 'home']]" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="won" select="count(saxon:node-set($update)//Game[Home[Team[. = $team]]/Result &gt; Away/Result])" />
<xsl:variable name="tied" select="count(saxon:node-set($update)//Game[Home[Team[. = $team]]/Result = Away/Result])" />
<xsl:variable name="lost" select="count(saxon:node-set($update)//Game[Home[Team[. = $team]]/Result &lt; Away/Result])" />
<WLTBreakdown Performance="home">
      <Won><xsl:value-of select="Won + $won" /></Won>
      <Lost><xsl:value-of select="Lost + $lost" /></Lost>
      <Tied><xsl:value-of select="Tied + $tied" /></Tied>
</WLTBreakdown>
</xsl:template>

<!--away details-->
<xsl:template match="WLTBreakdown[@Performance[. = 'away']]" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="won" select="count(saxon:node-set($update)//Game[Away[Team[. = $team]]/Result &gt; Home/Result])" />
<xsl:variable name="tied" select="count(saxon:node-set($update)//Game[Away[Team[. = $team]]/Result = Home/Result])" />
<xsl:variable name="lost" select="count(saxon:node-set($update)//Game[Away[Team[. = $team]]/Result &lt; Home/Result])" />
<WLTBreakdown Performance="away">
      <Won><xsl:value-of select="Won + $won" /></Won>
      <Lost><xsl:value-of select="Lost + $lost" /></Lost>
      <Tied><xsl:value-of select="Tied + $tied" /></Tied>
</WLTBreakdown>
</xsl:template>
</xsl:stylesheet>


for those wondering what is the equivalent in msxml, here is the stylesheet
msxml.xsl
=========
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes" />
<xsl:variable name="main" select="document(//main/@filename)" />
<xsl:variable name="update" select="document(//update/@filename)" />
<xsl:template match="/">
<xsl:apply-templates select="msxsl:node-set($main)/node()" mode="update" />
</xsl:template>
<xsl:template match="@* | node()" mode="update">
<xsl:copy><xsl:apply-templates select="@* | node()" mode="update" /></xsl:copy>
</xsl:template>

<!--total goals for-->
<xsl:template match="Goals/For" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="for" select="sum(msxsl:node-set($update)//Result[preceding-sibling::Team[1] = $team])" />
<For><xsl:value-of select=". + $for" /></For>
</xsl:template>

<!--total goals against-->
<xsl:template match="Goals/Against" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="home" select="sum(msxsl:node-set($update)//Game[Away/Team[. = $team]]/Home/Result)" />
<xsl:variable name="away" select="sum(msxsl:node-set($update)//Game[Home/Team[. = $team]]/Away/Result)" />
<Against><xsl:value-of select=". + $away + $home" /></Against>
</xsl:template>

<!--home details-->
<xsl:template match="WLTBreakdown[@Performance[. = 'home']]" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="won" select="count(msxsl:node-set($update)//Game[Home[Team[. = $team]]/Result &gt; Away/Result])" />
<xsl:variable name="tied" select="count(msxsl:node-set($update)//Game[Home[Team[. = $team]]/Result = Away/Result])" />
<xsl:variable name="lost" select="count(msxsl:node-set($update)//Game[Home[Team[. = $team]]/Result &lt; Away/Result])" />
<WLTBreakdown Performance="home">
      <Won><xsl:value-of select="Won + $won" /></Won>
      <Lost><xsl:value-of select="Lost + $lost" /></Lost>
      <Tied><xsl:value-of select="Tied + $tied" /></Tied>
</WLTBreakdown>
</xsl:template>

<!--away details-->
<xsl:template match="WLTBreakdown[@Performance[. = 'away']]" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="won" select="count(msxsl:node-set($update)//Game[Away[Team[. = $team]]/Result &gt; Home/Result])" />
<xsl:variable name="tied" select="count(msxsl:node-set($update)//Game[Away[Team[. = $team]]/Result = Home/Result])" />
<xsl:variable name="lost" select="count(msxsl:node-set($update)//Game[Away[Team[. = $team]]/Result &lt; Home/Result])" />
<WLTBreakdown Performance="away">
      <Won><xsl:value-of select="Won + $won" /></Won>
      <Lost><xsl:value-of select="Lost + $lost" /></Lost>
      <Tied><xsl:value-of select="Tied + $tied" /></Tied>
</WLTBreakdown>
</xsl:template>

</xsl:stylesheet>

xml output
==========
<?xml version="1.0" encoding="iso-8859-1"?>
<main><area><Name>North</Name>
<Team><TeamName>Manchester United</TeamName>
<League><Goals><For>103</For>
<Against>95</Against>
</Goals>
<WLTBreakdown Performance="home">
<Won>2</Won>
<Lost>0</Lost>
<Tied>0</Tied>
</WLTBreakdown>
<WLTBreakdown Performance="away">
<Won>1</Won>
<Lost>0</Lost>
<Tied>0</Tied>
</WLTBreakdown>
</League>
</Team>
<Team><TeamName>Manchester City</TeamName>
<League><Goals><For>51</For>
<Against>98</Against>
</Goals>
<WLTBreakdown Performance="home">
<Won>0</Won>
<Lost>0</Lost>
<Tied>1</Tied>
</WLTBreakdown>
<WLTBreakdown Performance="away">
<Won>0</Won>
<Lost>2</Lost>
<Tied>0</Tied>
</WLTBreakdown>
</League>
</Team>
</area>
</main>

0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6852734
Notes
=====
1. It is much simpler using the element transformation technique seen here to update the original transform.

2. To see the transform, I used the command line
java -jar saxon.jar "directive.xml" "saxon.xsl" and the output was exactly the same as that for msxml.xsl

3. by using the element transformation technique, we leave untouched elements that we wish to pass thru untouched like TeamName element and area.

4. The templates after
<xsl:template match="@* | node()" mode="update">
<xsl:copy><xsl:apply-templates select="@* | node()" mode="update" /></xsl:copy>
</xsl:template>

targets the elements that we interested in updating.

Regards,

Brandon Driesen
0
 
LVL 23

Accepted Solution

by:
b1xml2 earned 200 total points
ID: 6852756
a slight amendment to the saxon.xsl, i posted the debugged version LOL,

saxon.xsl
=========
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:saxon="http://icl.com/saxon" exclude-result-prefixes="saxon">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes" />
<xsl:variable name="main" select="document(//main/@filename)" />
<xsl:variable name="update" select="document(//update/@filename)" />
<xsl:template match="/">
<xsl:apply-templates select="saxon:node-set($main)/node()" mode="update" />
</xsl:template>
<xsl:template match="@* | node()" mode="update">
<xsl:copy><xsl:apply-templates select="@* | node()" mode="update" /></xsl:copy>
</xsl:template>

<!--total goals for-->
<xsl:template match="Goals/For" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="for" select="sum(saxon:node-set($update)//Result[preceding-sibling::Team[1] = $team])" />
<For><xsl:value-of select=". + $for" /></For>
</xsl:template>

<!--total goals against-->
<xsl:template match="Goals/Against" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="home" select="sum(saxon:node-set($update)//Game[Away/Team[. = $team]]/Home/Result)" />
<xsl:variable name="away" select="sum(saxon:node-set($update)//Game[Home/Team[. = $team]]/Away/Result)" />
<Against><xsl:value-of select=". + $away + $home" /></Against>
</xsl:template>

<!--home details-->
<xsl:template match="WLTBreakdown[@Performance[. = 'home']]" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="won" select="count(saxon:node-set($update)//Game[Home[Team[. = $team]]/Result &gt; Away/Result])" />
<xsl:variable name="tied" select="count(saxon:node-set($update)//Game[Home[Team[. = $team]]/Result = Away/Result])" />
<xsl:variable name="lost" select="count(saxon:node-set($update)//Game[Home[Team[. = $team]]/Result &lt; Away/Result])" />
<WLTBreakdown Performance="home">
     <Won><xsl:value-of select="Won + $won" /></Won>
     <Lost><xsl:value-of select="Lost + $lost" /></Lost>
     <Tied><xsl:value-of select="Tied + $tied" /></Tied>
</WLTBreakdown>
</xsl:template>

<!--away details-->
<xsl:template match="WLTBreakdown[@Performance[. = 'away']]" mode="update">
<xsl:variable name="team" select="preceding::TeamName[1]" />
<xsl:variable name="won" select="count(saxon:node-set($update)//Game[Away[Team[. = $team]]/Result &gt; Home/Result])" />
<xsl:variable name="tied" select="count(saxon:node-set($update)//Game[Away[Team[. = $team]]/Result = Home/Result])" />
<xsl:variable name="lost" select="count(saxon:node-set($update)//Game[Away[Team[. = $team]]/Result &lt; Home/Result])" />
<WLTBreakdown Performance="away">
     <Won><xsl:value-of select="Won + $won" /></Won>
     <Lost><xsl:value-of select="Lost + $lost" /></Lost>
     <Tied><xsl:value-of select="Tied + $tied" /></Tied>
</WLTBreakdown>
</xsl:template>

</xsl:stylesheet>

0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6860059
feedback, please?!
0
 
LVL 1

Author Comment

by:psilli1
ID: 6860304
Sorry, ur code gave me a vgood base as to how to use the node-set command, and from this i have been able to produce the XSL to create the new XML document.

Thanks for ur help!

Also, u may be able to help me on one last thing, I have a comma separated value in one of my elements, is there a way of spliting this then looping throuh the results creating a new element for each?

If not then no problem, and tnx 4 the help.
0
 
LVL 1

Expert Comment

by:vijayneema
ID: 7143341
Hi,

Have a look at this question too.

http://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=xml&qid=20321652

Thanks
vijayneema
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
What is Node.js? Node.js is a server side scripting language much like PHP or ASP but is used to implement the complete package of HTTP webserver and application framework. The difference is that Node.js’s execution engine is asynchronous and event…
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now