We help IT Professionals succeed at work.

XML Style Sheet that generates unique names from sibling nodes with identical names

Last Modified: 2013-11-18
Dear Experts:

We interface with an e-commerce site where Sales Orders are generated and exported to an XML file.  We transform that xml file, using a style sheet, that generates a second xml file.
This file is then imported to a relational db.  The  following code is a paired down example of the XML file that we receive, and must transform.  The problem comes in when we have to deal with the custom fields that may, or may not be, included in the XML file we receive.

In the element <customDocFields>,  we have up to six custom <field> elements that may be included in the XML we receive.  I say "may be", because these are user-defined fields and may be intialized.  If initalized, they appear in the XML, otherwise they do not.

We can have up to three <field> elements with a field type of "reseller_q" and three with a field type of "company_q".  Although the element tag ,<customDocfields> will always appear in the XML file we receive, the <field> elements may or may not.

What I am hoping to do, is ALWAYS generate six elements in our OUTPUT xml file, even when they don't all exist in the SOURCE xml file.  

<field> elements with a fieldType of "reseller_q", need to be mapped to child elements of the <docHeader> element with unique element names of their own.  The same is true for the <field> elements with a fieldType of "company_q".

What we need in our transformed XML file, is standardized output of six elements for the custom field names, and six field elements for the custom field text.  Again, whether they are in the SOURCE xml file or not.

It appears that I need some kind of for-each loop that generates 3 elements for each category of custom field.  Somehow the loop counter number is concatenated to the element name so we end up with:

  <reseller_q1_name> and also
  along with q2 and q3 elements for each of the above.

I have the same issue with the line items, but if someone can help me get over the hump understanding this, I believe I can apply the same concept there.

Any direction is greatly appreciated.

This is the Source XML file:
<?xml version="1.0" encoding="UTF-8"?>
<export_documents_response >
 <document documentNumber="64794" documentType="Sales Order">
   <field name="Cost Center" fieldType="reseller_q">"4600-000"</field>
   <field name="Invoice Number" fieldType="reseller_q">"0043001"</field>
   <field name="Shipping Notes" fieldType="reseller_q"/>
   <field name="Job ID" fieldType="company_q"/>
   <product lineItemNumber="1" productId="M004675190" >
     <field name="Department" fieldType="reseller_qp"/>
     <field name="Field Test 2" fieldType="reseller_qp"/>
     <field name="Field Test 3" fieldType="reseller_qp"/>
     <field name="Contract Type" fieldType="company_qp"/>
     <field name="Length" fieldType="company_qp"/>
The data below is what we are trying to achieve.
 <document> <docHeader>
   <reseller_q1_name>"Cost Center"</reseller_q1_name>
   <reseller_q2_name>"Invoice Number"</reseller_q2_name>
   <reseller_q3_name>"Shipping Notes"</reseller_q3_name>
   <company_q1_name>"Job ID"</company_q1_name>
   <reseller_qp2_name>"Field Test 2"</reseller_qp2_name>
   <reseller_qp3_name="Field Test 3"</reseller_qp3_name>
Below is the style sheet we currently use to transpose the SOURCE XML file.  We run into problems when there are multiple child nodes of the <customDocFields> and/or
<customLineFields> that have the same field type.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
<xsl:template match="export_documents_response">
<xsl:for-each select="documents/document">
  <documentNumber><xsl:value-of select="@documentNumber"/></documentNumber>
  <customDocFields_fieldType_reseller_q_name><xsl:value-of select=" _
    customDocFields/field /@fieldType='reseller_q']/@name"/> _
<xsl:for-each select="documents/document/itemList/product">
  <documentNumber><xsl:value-of select="../../@documentNumber"/></documentNumber>
  <customLineFields_fieldType_reseller_qp_name><xsl:value-of select="customLineFields/field _
  <customLineFields_fieldType_reseller_qp> _
   <xsl:value-of select="customLineFields/field[@fieldType='reseller_qp']"/>

Open in new window

Watch Question

Information Architect
Top Expert 2006
This one is on us!
(Get your first solution completely free - no credit card required)


Thanks Geert,

I will give it a try and let you know how it works out.


The solution you provided worked great.  I really appreciate  the time you spent.  Thamk you.
Gertone (Geert Bormans)Information Architect
Top Expert 2006

Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.