Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

i am trying to generate multiple xml file using xslt. my *input.xm*l file is

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     
<soapenv:Body>
 <ns1:getDocumentByKeyResponse   soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"   xmlns:ns1="http://www.taleo.com/ws/integration/toolkit/2005/07">
 <Document xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
<Attributes>
 <Attribute name="duration">0:00:00.084</Attribute>
 <Attribute name="count">7</Attribute>
<Attribute name="entity">Requisition</Attribute>
<Attribute name="mode">XML</Attribute>
<Attribute name="version">http://www.taleo.com/ws/tee800/2009/01</Attribute>
</Attributes>
<Content>
<ExportXML xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
 <record>
<field name="ContestNumber">1300000F</field>
  <field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000H</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000T</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000018</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">000123</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000R</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000016</field>
 <field name="ManagerRequisitionTitle">Project Manager</field>
 </record>
</ExportXML>
</Content>
</Document>
</ns1:getDocumentByKeyResponse>
</soapenv:Body>
</soapenv:Envelope>

my xslt is sample.xslt

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pDest" select="'file:///c:/temp/'"/>
<xsl:template match="*[starts-with(name(),'ExportXML')]">
<xsl:for-each select="record">
<xsl:result-document href="{$pDest}section{position()}.xml">
<JobPositionPostings>
<JobPositionPosting>
<xsl:apply-templates select="*:field[starts-with(@name,'ContestNumber')]"/>
 <JobDisplayOptions>
 <xsl:apply-templates select="*:field[starts-with(@name,'ManagerRequisitionTitle')]"/>
 </JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

i am not getting proper output. i want that every input tag data comes in separate file like this

  <?xml version="1.0" encoding="UTF-8"?>
  </JobPositionPostings>
  <JobPositionPostings>
  <JobPositionPosting>
 <contestnumber>13000016</contestnumber>
 <JobDisplayOptions>
 <managerrequisitiontitle>Project Manager</managerrequisitiontitle>
 </JobDisplayOptions>
 </JobPositionPosting>
 </JobPositionPostings>

please suggest me any solution.thanks in advance.

share|improve this question
    
I think that is hard if not impossible to achieve with xslt parsing alone.... –  rene Aug 11 '13 at 19:28

2 Answers 2

up vote 0 down vote accepted

You've got a couple of problems with your XSLT, mainly around namespaces. You start off with the following template match

<xsl:template match="*[starts-with(name(),'ExportXML')]">

This is fine, but you only really need to do this if you know the ExportXML element belongs to a namespace (which in your case it does), but do not what the namespace will be. Ideally though, you should be using "local-name()" here though, not "name()" because name() will include any namespace prefix, and so would not work in the following case.

<x:ExportXML xmlns:x="http://www.taleo.com/ws/integration/toolkit/2005/07">

Anyway, the problem occurs with your next line of XSLT

<xsl:for-each select="record">

This is looking for a record element not part of any namespace, when the record element in your XML is part of the same namespace as ExportXML (as are all its descendants). You should be using the similar syntax here (assuming you genuinely don't know the namespace in advance)

<xsl:for-each select="*[starts-with(local-name(),'record')]">

The next problem is with the code you use to get the value of "ContestNumber" (and "ManagerRequisitionTitle"):

<xsl:apply-templates select="*:field[starts-with(@name,'ContestNumber')]"/>

Aside from being syntactically invalid, you also have the same issue with the field element being in the namespace too, so you need to do this

<xsl:apply-templates select="*[starts-with(local-name(), 'field')][@name='ContestNumber']"/>

Although using xsl:apply-templates is probably not needed here, so xsl:value-of should do.

Try this XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:strip-space elements="*"/>
   <xsl:param name="pDest" select="'file:///c:/temp/'"/>
   <xsl:template match="*[starts-with(local-name(),'ExportXML')]">
      <xsl:for-each select="*[starts-with(local-name(),'record')]">
         <xsl:result-document href="{$pDest}section{position()}.xml">
            <JobPositionPostings>
               <JobPositionPosting>
                  <xsl:value-of select="*[starts-with(local-name(), 'field')][@name='ContestNumber']"/>
                  <JobDisplayOptions>
                     <xsl:value-of select="*[starts-with(local-name(), 'field')][@name='ManagerRequisitionTitle']"/>
                  </JobDisplayOptions>
               </JobPositionPosting>
            </JobPositionPostings>
         </xsl:result-document>
      </xsl:for-each>
   </xsl:template>

   <xsl:template match="*[starts-with(local-name(), 'Attributes')]"/>
</xsl:stylesheet>

Do also note the template to match, and ignore Attributes because otherwise XSLT's built-in templates will match these, and output the text value.

Of course, if you did now that the namespace was always going to be the same, you could simplify your XSLT by declaring the namespace. This XSLT should also work:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
   <xsl:strip-space elements="*"/>
   <xsl:param name="pDest" select="'file:///c:/temp/'"/>
   <xsl:template match="ExportXML">
      <xsl:for-each select="record">
         <xsl:result-document href="{$pDest}section{position()}.xml">
            <JobPositionPostings>
               <JobPositionPosting>
                  <xsl:value-of select="field[@name='ContestNumber']"/>
                  <JobDisplayOptions>
                     <xsl:value-of select="field[@name='ManagerRequisitionTitle']"/>
                  </JobDisplayOptions>
               </JobPositionPosting>
            </JobPositionPostings>
         </xsl:result-document>
      </xsl:for-each>
   </xsl:template>
   <xsl:template match="Attributes"/>
</xsl:stylesheet>

EDIT: One way to test the template is matching is to temporarily change the XSLT to not use xsl:result-document. Instead, change it to output a normal element at this point

<!-- <xsl:result-document href="{$pDest}section{position()}.xml"> -->
<file href="{$pDest}section{position()}.xml">
   <JobPositionPostings>...</JobPositionPostings>
</file>

Then, use an XSLT testing tool (such as http://xslttest.appspot.com/) and test your XML and amended XSLT, to see if multiple file elements are being created. If so, you should be able to change back to using xsl:result-document.

share|improve this answer
    
thanks for ur reply.but my problem still unsolved.i used first xslt suggested by you but i m not getting any output.i think this statement is not returning any thing. <xsl:template match="*[starts-with(local-name(),'ExportXML')]"> due to containg name space in that.is there any solution for namespace containg tag consider as root tag. –  user1906222 Aug 12 '13 at 9:17
    
The template should match the element, regardless of namespace, as explained in the answer. Does your XSLT have any other templates other than the ones shown in your question? Note that I have amended my answer to show how you could possibly test the template is actually matching anything. –  Tim C Aug 12 '13 at 12:43
    
Hi tim ,again thanku.really u helped me a lot. now i am getting proper output.the same thing when i am doing my taleo connect client tool to trans form its not generating any output. i think error with the transform taleo tool only.i got seven output file using that file href.thanku again –  user1906222 Aug 12 '13 at 13:51

Two solutions are below, though I had to make some assumptions because you are not clear on your requirements. The first solution soap.xsl uses the pull style where elements are manifest in your stylesheet. The second solution soap2.xsl uses the push style where elements are synthesized from the attribute names. I didn't know what more you wanted to do with your stylesheet after these basics were covered.

t:\ftemp>type soap.xml 
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">     
<soapenv:Body>
 <ns1:getDocumentByKeyResponse   soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"   xmlns:ns1="http://www.taleo.com/ws/integration/toolkit/2005/07">
 <Document xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
<Attributes>
 <Attribute name="duration">0:00:00.084</Attribute>
 <Attribute name="count">7</Attribute>
<Attribute name="entity">Requisition</Attribute>
<Attribute name="mode">XML</Attribute>
<Attribute name="version">http://www.taleo.com/ws/tee800/2009/01</Attribute>
</Attributes>
<Content>
<ExportXML xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
 <record>
<field name="ContestNumber">1300000F</field>
  <field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000H</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000T</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000018</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">000123</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000R</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000016</field>
 <field name="ManagerRequisitionTitle">Project Manager</field>
 </record>
</ExportXML>
</Content>
</Document>
</ns1:getDocumentByKeyResponse>
</soapenv:Body>
</soapenv:Envelope>
t:\ftemp>rmdir /s /q temp 

t:\ftemp>call xslt2 soap.xml soap.xsl 

t:\ftemp>type temp\section1.xml 
<JobPositionPostings>
   <JobPositionPosting>
      <contestnumber>1300000F</contestnumber>
      <JobDisplayOptions>
         <managerrequisitiontitle>Project Manager</managerrequisitiontitle>
      </JobDisplayOptions>
   </JobPositionPosting>
</JobPositionPostings>

t:\ftemp>dir temp 
 Volume in drive T is VBOX_t
 Volume Serial Number is 0E00-0001

 Directory of t:\ftemp\temp

2013-08-11  17:00               269 section1.xml
2013-08-11  17:00               269 section2.xml
2013-08-11  17:00               269 section3.xml
2013-08-11  17:00               269 section4.xml
2013-08-11  17:00               267 section5.xml
2013-08-11  17:00               269 section6.xml
2013-08-11  17:00               269 section7.xml
               7 File(s)          1,881 bytes
               0 Dir(s)   8,351,150,080 bytes free

t:\ftemp>type soap.xsl 
<xsl:stylesheet version="2.0"
  xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:param name="pDest" select="'temp/'"/>

<xsl:template match="/">
  <xsl:for-each select="//record">
    <xsl:result-document href="{$pDest}section{position()}.xml">
      <JobPositionPostings>
        <JobPositionPosting>
          <contestnumber>
            <xsl:value-of select="field[@name='ContestNumber']"/>
          </contestnumber>
          <JobDisplayOptions>
            <managerrequisitiontitle>
              <xsl:value-of select="field[@name='ManagerRequisitionTitle']"/>
            </managerrequisitiontitle>
          </JobDisplayOptions>
        </JobPositionPosting>
      </JobPositionPostings>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>rmdir /s /q temp 

t:\ftemp>call xslt2 soap.xml soap2.xsl 

t:\ftemp>type temp\section2.xml 
<JobPositionPostings>
   <JobPositionPosting>
      <contestnumber>1300000H</contestnumber>
      <JobDisplayOptions>
         <managerrequisitiontitle>Project Manager</managerrequisitiontitle>
      </JobDisplayOptions>
   </JobPositionPosting>
</JobPositionPostings>

t:\ftemp>dir temp 
 Volume in drive T is VBOX_t
 Volume Serial Number is 0E00-0001

 Directory of t:\ftemp\temp

2013-08-11  17:00               269 section1.xml
2013-08-11  17:00               269 section2.xml
2013-08-11  17:00               269 section3.xml
2013-08-11  17:00               269 section4.xml
2013-08-11  17:00               267 section5.xml
2013-08-11  17:00               269 section6.xml
2013-08-11  17:00               269 section7.xml
               7 File(s)          1,881 bytes
               0 Dir(s)   8,351,670,272 bytes free

t:\ftemp>type soap2.xsl 
<xsl:stylesheet version="2.0" 
  xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:param name="pDest" select="'temp/'"/>

<xsl:template match="/">
  <xsl:for-each select="//record">
    <xsl:result-document href="{$pDest}section{position()}.xml">
      <JobPositionPostings>
        <JobPositionPosting>
          <xsl:apply-templates select="field[@name='ContestNumber']"/>
          <JobDisplayOptions>
            <xsl:apply-templates
                     select="field[@name='ManagerRequisitionTitle']"/>
          </JobDisplayOptions>
        </JobPositionPosting>
      </JobPositionPostings>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template>

<xsl:template match="field">
  <xsl:element name="{lower-case(@name)}">
    <xsl:value-of select="."/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>rem Done! 
share|improve this answer
    
hi ken,thanks for reply. i used second xslt2.0 code and i got only one otput file name section1.xml <JobPositionPostings> please suggest me how to get all record tag data in seprate xml file. <JobPositionPosting> <contestnumber>13000016</contestnumber> <JobDisplayOptions> <managerrequisitiontitle>Project Manager</managerrequisitiontitle> </JobDisplayOptions> </JobPositionPosting> </JobPositionPostings> –  user1906222 Aug 12 '13 at 9:25
    
Usually when I post a solution to StackOverflow, as I have above, I include a complete transcript of the invocation of the stylesheet. If you look above, you can see that I delete the directory, I run the stylesheet, I note the creation of the files in the directory, then I show you the contents of the stylesheet. This is evidence that my stylesheet already does what you ask for. I am running the Saxon processor, which is the gold standard for XSLT processors. If you are not getting the results that I am getting, then I would question the quality of the XSLT processor you are using. –  G. Ken Holman Aug 12 '13 at 14:30
    
hi ken really sorry if i told anything wrong.ur solution is correct only i tested on xslttest.appspot.com here.i m totally new to this xslt.i am trying to learn.i am using taleo connect client tool for transformation its on xslt2.0 .more than that i dont have knowledge.thanks for helping me.there is parser tool problem only due to that i m not getting output.oncae again thanks for help. –  user1906222 Aug 12 '13 at 16:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.