0

hi guys so ive been having a bit of trouble with his one i want to do a complete copy of an xml and replace of a fields within the data this is the code i have been using but it only transforms the first field and doesnt copy the xml im using eclipse with the default xsl transformation to do the work as it seems its the only processor i can get working correctly anyway here is the xsl template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:variable name="replacedURL">
        <xsl:call-template name="string-replace-all">
            <xsl:with-param name="text" select="/hotels/hotel/hotel_link/text()"/>
            <xsl:with-param name="replace" select="'[[PARTNERID]]'"/>
            <xsl:with-param name="by" select="'13252'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$replacedURL"/>
</xsl:template>
<xsl:template name="string-replace-all">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="by"/>
    <xsl:choose>
        <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)"/>
            <xsl:value-of select="$by"/>
            <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text" select="substring-after($text,$replace)"/>
                <xsl:with-param name="replace" select="$replace"/>
                <xsl:with-param name="by" select="$by"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

then this is a sample of the xml

<hotel>
<hotel_ref>235128</hotel_ref>
<hotel_name>Afghanistan Dolores test - non bookable</hotel_name>
<hotel_star>2</hotel_star>
<hotel_address>afghanistan test</hotel_address>
<hotel_city>afghanistan</hotel_city>
<hotel_pcode /><hotel_county />
<hotel_country>Afghanistan</hotel_country>
<hotel_description>hotel description text</hotel_description>
 <alternate_description>hotel description text</alternate_description>
 <hotel_directions>kjlaklka</hotel_directions>
 <alternate_directions>kjlaklka</alternate_directions>
<hotel_link> http://www.website.com/en/p[[PARTNERID]]/hotel-reservations/235128_afghanistan-dolores-test-non-bookable-afghanistan.aspx</hotel_link>
<customerrating>0</customerrating>
<PricesFrom>10.0000</PricesFrom>
<MaxPrice>800.00</MaxPrice>
<CurrencyCode>GBP</CurrencyCode>
<images />
<geo_code><lat>34.53824</lat><long>69.18640</long></geo_code>
<hotel_facilities />
<checkin_time>12/07/2011 14:00:00</checkin_time>
<checkout_time>12/07/2011 11:00:00</checkout_time>
 <cancellationpolicy>2 days prior to stay</cancellationpolicy>
<cancellationtext /><accommodation_type /><hotel_appeals />
<hotel_star_accreditor />
<hotel_total_rooms>45</hotel_total_rooms>
<hotel_credit_cards>
<CreditCard><credit_card_id>4</credit_card_id><credit_card_name>American Express</credit_card_name></CreditCard><CreditCard><credit_card_id>5</credit_card_id><credit_card_name>Switch/Maestro</credit_card_name></CreditCard><CreditCard><credit_card_id>1</credit_card_id><credit_card_name>Visa/Delta</credit_card_name></CreditCard><CreditCard><credit_card_id>2</credit_card_id> <credit_card_name>Mastercard</credit_card_name></CreditCard></hotel_credit_cards>  
<hotel_city_taxes><CityTax><Type /><Value /><OptedIn /><IsCityTaxArea /></CityTax>
</hotel_city_taxes> 
</hotel>

the whole file is around 500 megabytes would i need a special proccessor to do this or would eclipses built in xsl transform do the job

dom
  • 254
  • 1
  • 4
  • 18
  • AFAIK, oXygen can be used as an eclipse plugin. In this case you can use oXygen with Saxon 9.x and run the the XSLT 2.0 RegEx - based solution I gave for your previous question. – Dimitre Novatchev Jul 28 '12 at 18:06

1 Answers1

1

Copy everything while modifying only one little piece is always a case for the identity template:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <!-- ...except for the text in <hotel_link> elements: -->
  <xsl:template match="hotel_link/text()">
    <xsl:call-template name="string-replace-all">
      <xsl:with-param name="text"    select="."/>
      <xsl:with-param name="replace" select="'[[PARTNERID]]'"/>
      <xsl:with-param name="by"      select="'13252'"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="string-replace-all">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="by"/>
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text,$replace)"/>
        <xsl:value-of select="$by"/>
        <xsl:call-template name="string-replace-all">
          <xsl:with-param name="text" select="substring-after($text,$replace)"/>
          <xsl:with-param name="replace" select="$replace"/>
          <xsl:with-param name="by" select="$by"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

(The string-replace-all template has been taken from this answer.)

That being said, if your input file is 500 MB, you should not use an XSLT transformation, as this builds a complete DOM of the input in memory before it can begin. A DOM is always a lot larger than the XML document it is based on, so you could get into memory trouble here. Of course you can try it anyway.

You should write a small SAX parser instead. This will be faster and more memory-efficient.

Community
  • 1
  • 1
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • that seemed to work i ran it through eclipse xsl transformation with xalan as processor i got a warning complaining failed socket connection after 60 attempts i had the eclipse .ini set to 4GB seemed to do it upon inspection the file is 700KB smaller but i would expect that with the loss of characters so i think even though i had an error it comleted successfully thank you for your help – dom Jul 27 '12 at 17:00