Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old December 13th, 2010, 01:41 AM
Authorized User
 
Join Date: Dec 2010
Posts: 16
Thanks: 5
Thanked 0 Times in 0 Posts
Default how to produce single output from multiple sources?

I have a set of source XML files FILE1, ..., FILEn that I am converting using XSLT to another set of XML files. Each resulting file has the following structure:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<!-- stuff corresponding to FILEi -->
</data>
I use Saxon. What I actually need is a single output XML file like this:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<!-- stuff corresponding to FILE1 -->
<!-- stuff corresponding to FILE2 -->
...
<!-- stuff corresponding to FILEn -->
</data>
How can I achieve this? Can I use Saxon to do this many-to-one conversion at once, or do I need to run some type of postprocessing concatenation of the resulting XMLs into one? If latter, what tool should I use? I need to run this from command line.

Thanks!
Reply With Quote
  #2 (permalink)  
Old December 13th, 2010, 04:43 AM
samjudson's Avatar
Friend of Wrox
Points: 8,687, Level: 40
Points: 8,687, Level: 40 Points: 8,687, Level: 40 Points: 8,687, Level: 40
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Aug 2007
Location: Newcastle, , United Kingdom.
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

You simply need to use the document() function to load each XMl file in turn.

[code]
<data>
<xsl:for-each select="1 to 10">
<xsl:apply-templates select="document(concat('FILE',.))/data/*"/>
</xsl:for-each>
</data>
[code]

Then you'd have templates to process the contents of the file. Or you could change the apply-template to a copy-of if you simply want to copy everything.
__________________
/- Sam Judson : Wrox Technical Editor -/

Think before you post: What have you tried?
Reply With Quote
  #3 (permalink)  
Old December 13th, 2010, 05:31 AM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Or if the files are all in a directory, you can use

Code:
<xsl:template name="main">
  <data>
     <xsl:copy-of select="collection('file:///dir/?select=FILE*.xml')"/>
  </data>
</xsl:template>
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Reply With Quote
  #4 (permalink)  
Old December 13th, 2010, 11:30 AM
Authorized User
 
Join Date: Dec 2010
Posts: 16
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by mhkay View Post
Or if the files are all in a directory, you can use
Sorry for being slow, but I need this to be spelled out for me in more detail.

-----

Now I have an input folder "c:/data/XMLin" that contains a bunch of source XML files. I also have an XSL transform that creates a set of corresponding output files that have the form
Code:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<!-- stuff corresponding to FILEi -->
</data>
These files are stored in a folder "c:/data/XMLout". What I need to do is to create a single XML file in the form
Code:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<!-- stuff corresponding to FILE1 -->
<!-- stuff corresponding to FILE2 -->
...
<!-- stuff corresponding to FILEn -->
</data>
----------

So do I need to run my existing transform, generate the output files as I do now and then apply what you suggest to produce the single output? Or do I do it all in one step? What would be the command line options for Saxon to do this?

Thanks much!
Reply With Quote
  #5 (permalink)  
Old December 13th, 2010, 12:17 PM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Are you currently using the command line option to take a directory as input and produce a directory as output? It's not clear to me where you are starting from.

Do you want the single output file *as well as* the existing output files, or as a replacement for them?

I'd suggest doing a single transformation that uses collection() to read all the input files, and this single transformation produces multiple output files using xsl:result-document.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Reply With Quote
  #6 (permalink)  
Old December 13th, 2010, 12:21 PM
Authorized User
 
Join Date: Dec 2010
Posts: 16
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by mhkay View Post
Are you currently using the command line option to take a directory as input and produce a directory as output?
Yes

Quote:
Originally Posted by mhkay View Post
Do you want the single output file *as well as* the existing output files, or as a replacement for them?
Single output is enough. If I can avoid creating the individual output files I am creating now that would be great. If I have to do it in a two-step process, that's fine too.
Reply With Quote
  #7 (permalink)  
Old December 13th, 2010, 12:33 PM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

OK. I guess "stuff corresponding to X" doesn't mean "a copy of X" as I supposed, but "the result of transforming X", using the same transformation as you are currently using to generate each output file individually.

So, take your existing transformation, add

Code:
<xsl:template name="main">
  <data>
     <xsl:apply-templates select="collection('file:///c:/data/XMLin/?select=FILE*.xml')"/>
  </data>
</xsl:template>
and then invoke it from the command line with no -s option, with -o specifying the name of the single output file, and with -it:main
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Reply With Quote
  #8 (permalink)  
Old December 13th, 2010, 01:46 PM
Authorized User
 
Join Date: Dec 2010
Posts: 16
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by mhkay View Post
OK. I guess "stuff corresponding to X" doesn't mean "a copy of X" as I supposed, but "the result of transforming X", using the same transformation as you are currently using to generate each output file individually.

and then invoke it from the command line with no -s option, with -o specifying the name of the single output file, and with -it:main
Michael,

When I ran it like this:

Code:
Transform.exe -xsl:myXform.xsl -it:main -o:"C:\Data\XMLout"
I got

Code:
Output is a directory, but input is not
So I reran it after adding

Code:
-s:"C:\Data\XMLin"
and it worked by producing N identical copies of output files containing output from all N input files. I would prefer to generate just one file but this works too. Thanks!

However, I just realized that I forgot about something when posting my original question. When processing each individual file, I pass inside the transform a parameter whose value is different for each source file. So before, when I was processing one source file at a time, I would do something like this:

Code:
Transform.exe -s:inFILE1.xml -xsl:myXform.xsl -o:outFILE1.xml param=100
Transform.exe -s:inFILE2.xml -xsl:myXform.xsl -o:outFILE2.xml param=200
...
Now I execute just one command, so how can I pass inside the whole array of param values? If I can't, then I must go back to producing one output XML for each input XML. IN this case I have to concatenate afterwards. How can I do that?Again, in this case each output XML will have its entire content in a single <data></data> element and I will have to pull out this content and dump it into a single XML output with a <data></data> element.

Thanks much.
Reply With Quote
  #9 (permalink)  
Old December 13th, 2010, 01:56 PM
mhkay's Avatar
Wrox Author
Points: 18,481, Level: 59
Points: 18,481, Level: 59 Points: 18,481, Level: 59 Points: 18,481, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,960
Thanks: 0
Thanked 292 Times in 287 Posts
Default

As I said before, -o should be the name of the single output file - not a directory.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Reply With Quote
  #10 (permalink)  
Old December 14th, 2010, 11:33 AM
Authorized User
 
Join Date: Dec 2010
Posts: 16
Thanks: 5
Thanked 0 Times in 0 Posts
Default

At this point I have the following Xform:

Code:
<xsl:transform
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 version="2.0"
 exclude-result-prefixes="xs"
>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

xsl:template name="main">
<data>
     <xsl:apply-templates select="collection('file:///C:/Data/XMLout/?select=*.xml') "/> 
</data>	 
</xsl:template>  

<xsl:template match="data">
     <xsl:copy-of select="*|text()|comment()"/> 
</xsl:template>
I invoke Saxon as follows:

Code:
Transform.exe -xsl:merge.xsl -o:"C:\Data\merged.xml" -it:main
It partially works. What it does is that it appears to create an XML document with a single top-level <data> eleent, as I want. However, it cuts output midway and produces the following message:

Code:
Error on line 1409 column 30 of merged.xml:
  SXXP0003: Error reported by XML parser: XML document structures must start and end within the same entity.
Transformation failed: Run-time errors were reported
Line 1409 is the last one in the malformed output and the last three lines look like this:
Code:
	<container type="Entity" id="262" shortName="الفلسطينيين">
      <property name="Type">LOCATION</property>
      <property name="Value">
Note that the source is a UTF-8 XML that contains some Arabic text in it.

I checked the source file from which the output is being generated and it looks well-formed. What else can be going wrong here?

Thanks much
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to produce this output in XSLT 1.0 UndeadHalfOrc XSLT 1 December 9th, 2010 04:34 AM
Multiple Datasets from multiple Data Sources SQL_Hacker Reporting Services 1 June 18th, 2008 02:25 PM
Save (output to) multiple files from single click moo_desanta Classic ASP Basics 2 June 23rd, 2006 02:00 AM
Multiple file input single file output.... jdm_mboy Biztalk 1 July 2nd, 2003 03:35 AM



All times are GMT -4. The time now is 04:20 AM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.