2

I need xslt to transform, My Xml is as below

 <OrderReferences>
            <OrderRef>
              <OrderRef>OrderRef1</OrderRef>
              <Type>ERP</Type>
            </OrderRef>
            <OrderRef>
              <OrderRef>OrderRef2</OrderRef>
              <Type>CUSTOMER</Type>
            </OrderRef>
            <OrderRef>
              <OrderRef>OrderRef3</OrderRef>
              <Type>EXT</Type>
            </OrderRef>
          </OrderReferences>

My Output from this should be

<OrderReference> (OrderReference for ERP should appear here) </OrderReference>
<OrderReferenceCustomer> (CustomerReference for Customer should appear here) </OrderReferenceCustomer>
<OrderReferenceExternal> (ExtReference for EXT should appear here) </OrderReferenceExternal>

Let me know if this is achievable. XSLT 1.0 version preferrable as i want this for .Net. Thanks.

Tim C
  • 70,053
  • 14
  • 74
  • 93
KRP
  • 131
  • 1
  • 3
  • 15
  • Where in the original XML do you have `CustomerReference` and `ErpOrderReference`? – Oliver May 03 '12 at 08:40
  • ErpOrderReference, ErpCustomerReference, ErpExtReference are the objects where i want to put these data to. I need an xslt some thing like this. – KRP May 03 '12 at 08:46
  • Well, the correct answer is "yes, it's achievable". Don't you think you should try it yourself and come back if you have a specific problem? – Adrian Mouat May 03 '12 at 09:22

2 Answers2

2

You need to make use of the xsl:element to create new element names based on the Type element. Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="OrderRef">
      <xsl:element name="Erp{substring(Type, 1, 1)}{translate(substring(Type, 2, string-length(Type) - 1), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')}Reference">
         <xsl:value-of select="OrderRef" />
      </xsl:element>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

When this is applied to your sample XML, the following is output

<OrderReferences>
   <ErpErpReference>OrderRef1</ErpErpReference>
   <ErpCustomerReference>OrderRef2</ErpCustomerReference>
   <ErpExtReference>OrderRef3</ErpExtReference>
</OrderReferences>

This should cope with Type elements containing any value.

Tim C
  • 70,053
  • 14
  • 74
  • 93
1

This short and simple transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="OrderRef[Type='ERP']">
     <OrderReference><xsl:value-of select="OrderRef"/></OrderReference>
 </xsl:template>

 <xsl:template match="OrderRef[Type='CUSTOMER']">
     <OrderReferenceCustomer><xsl:value-of select="OrderRef"/></OrderReferenceCustomer>
 </xsl:template>

 <xsl:template match="OrderRef[Type='EXT']">
     <OrderReferenceExternal><xsl:value-of select="OrderRef"/></OrderReferenceExternal>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<OrderReferences>
    <OrderRef>
        <OrderRef>OrderRef1</OrderRef>
        <Type>ERP</Type>
    </OrderRef>
    <OrderRef>
        <OrderRef>OrderRef2</OrderRef>
        <Type>CUSTOMER</Type>
    </OrderRef>
    <OrderRef>
        <OrderRef>OrderRef3</OrderRef>
        <Type>EXT</Type>
    </OrderRef>
</OrderReferences>

produces the exact wanted, correct result (unlike the currently accepted answer):

<OrderReference>OrderRef1</OrderReference>
<OrderReferenceCustomer>OrderRef2</OrderReferenceCustomer>
<OrderReferenceExternal>OrderRef3</OrderReferenceExternal>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431