replace characters from selected value - xslt

I'm new in xslt and I have to transform a xml file to html. I am able to retrieve my information but I want to shrink some strings. I dont know how to call the xsl template to my value-of select call. can someone help me?
EDIT: I changed my rplace 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="/">
<html>
<body>
<h2>Changelog</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:center">Action</th>
<th style="text-align:center">Author</th>
<th style="text-align:center">Path</th>
<th style="text-align:center">Filename</th>
<th style="text-align:center">Comment</th>
</tr>
<xsl:for-each select="//Field[#name='CPEntries']/List/Item">
<tr>
<td><xsl:value-of select="Field[#name='type']/Item/#id"/></td>
<td><xsl:value-of select="Field[#name='user']/Item/#id"/></td>
<td><xsl:value-of select="Field[#name='member']/Item/#id"/></td>
<td><xsl:value-of select="Field[#name='summary']"/></td>
<td>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="input" select="Field[#name='configpath']/Item/#id"/>
<xsl:with-param name="replace" select="'E'" />
<xsl:with-param name="by" select="'...'" />
</xsl:call-template>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</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="$text = '' or $replace = ''or not($replace)" >
<!-- Prevent this routine from hanging -->
<xsl:value-of select="$text" />
</xsl:when>
<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>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Changelog</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:center">Action</th>
<th style="text-align:center">Author</th>
<th style="text-align:center">Path</th>
<th style="text-align:center">Filename</th>
<th style="text-align:center">Comment</th>
</tr>
<xsl:for-each select="//Field[#name='CPEntries']/List/Item">
<tr>
<td><xsl:value-of select="Field[#name='type']/Item/#id"/></td>
<td><xsl:value-of select="Field[#name='user']/Item/#id"/></td>
<td><xsl:value-of select="Field[#name='member']/Item/#id"/></td>
<td><xsl:value-of select="Field[#name='summary']"/></td>
<td>
<xsl:call-template name="search-and-replace">
<xsl:with-param name="input" select=value-of select="Field[#name='configpath']/Item/#id"/>
<xsl:with-param name="search-string" select="STRINGTOSEARCHFOR"/>
<xsl:with-param name="replace-string" select="..."/>
</xsl:call-template>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="search-and-replace">
  <xsl:param name="input"/>
  <xsl:param name="search-string"/>
  <xsl:param name="replace-string"/>
  <xsl:choose>
    <xsl:when test="$search-string and contains($input,$search-string)">
      <xsl:value-of select="substring-before($input,$search-string)"/>
      <xsl:value-of select="$replace-string"/>
      <xsl:call-template name="search-and-replace">
        <xsl:with-param name="input" select="substring-after($input,$search-string)"/>
        <xsl:with-param name="search-string" select="$search-string"/>
        <xsl:with-param name="replace-string" select="$replace-string"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$input"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
</xsl:stylesheet>
EDIT 2: This is an example entry of my xml file
<Field name="CPEntries">
<List elementType="item">
<Item id="PATH" context="775412:4" modelType="si.ChangePackage.Entry" displayId="PATH:Update">
<Field name="type">
<Item id="Update" modelType="si.ChangePackage.Entry.Action" displayId="Update">
<Field name="action">
<Value dataType="string">Update</Value>
</Field>
<Field name="previousState">
<Item id="FILE.c" modelType="cpName" displayId="FILE.c">
<Field name="oldRevision">
<Item id="1.63" modelType="si.Revision" displayId="1.63">
</Item>
</Field>
</Item>
</Field>
<Field name="isCommitted">
<Value dataType="boolean">true</Value>
</Field>
<Field name="isDeferred">
<Value dataType="boolean">false</Value>
</Field>
<Field name="isDiscarded">
<Value dataType="boolean">false</Value>
</Field>
<Field name="isPending">
<Value dataType="boolean">false</Value>
</Field>
<Field name="isExclusive">
<Value dataType="boolean">false</Value>
</Field>
</Item>
</Field>
<Field name="membertype">
<Value dataType="string">Member</Value>
</Field>
<Field name="member">
<Item id="FILE.c" modelType="si.Member" displayId="FILE.c">
</Item>
</Field>
<Field name="revision">
<Item id="1.64" modelType="si.Revision" displayId="1.64">
</Item>
</Field>
<Field name="user">
<Item id="Lastname, Firstname (uid)" modelType="si.User" displayId="Lastname, Firstname (uid)">
<Field name="fullname">
<Value dataType="string"></Value>
</Field>
</Item>
</Field>
<Field name="timestamp">
<Value dataType="datetime">2017-05-23T09:09:40</Value>
</Field>
<Field name="project">
<Item id="PROJECTPATH" modelType="si.Project" displayId="PROJECTPATH">
</Item>
</Field>
<Field name="configpath">
<Item id="CONFIGPATH" modelType="si.Project" displayId="CONFIGPATH">
</Item>
</Field>
<Field name="location">
<Value dataType="string">CONFIGPATH/efils.c</Value>
</Field>
<Field name="variant">
<Value></Value>
</Field>
<Field name="id">
<Item id="775412:4" modelType="si.ChangePackage" displayId="775412:4">
</Item>
</Field>
<Field name="summary">
<Value dataType="string">teststring</Value>
</Field>
<Field name="server">
<Item id="server.net" modelType="si.Server" displayId="server.net">
<Field name="hostname">
<Value dataType="string">server.net</Value>
</Field>
<Field name="port">
<Value dataType="int">7001</Value>
</Field>
</Item>
</Field>
<Field name="linesadded">
<Value dataType="long">281</Value>
</Field>
<Field name="linesdeleted">
<Value dataType="long">278</Value>
</Field>
<Field name="bytesadded">
<Value dataType="long">0</Value>
</Field>
<Field name="bytesdeleted">
<Value dataType="long">0</Value>
</Field>
<Field name="istext">
<Value dataType="boolean">true</Value>
</Field>
</Item>
[...]

I think you need to do this...
<xsl:call-template name="search-and-replace">
<xsl:with-param name="input" select="Field[#name='configpath']/Item/#id"/>
<xsl:with-param name="search-string" select="'STRINGTOSEARCHFOR'"/>
<xsl:with-param name="replace-string" select="'STRINGTOREPLACE'"/>
</xsl:call-template>
Note the apostrophes around 'STRINGTOSEARCHFOR' (and 'STRINGTOREPLACE'). Without this, they would be treated as xpath expressions, and so it would try to look for an element called STRINGTOSEARCHFOR, rather than use the literal string value.

Related

How to return single value when duplicate results in XSLT variable?

Using XSLT 1.0 (Xalan)-
From this segment of input XML...
<LineComponent>
<Adjustment Type="Addition" Category="Premium" SubCategory="D240">
<Description>Freight</Description>
<Value>10.00</Value>
</Adjustment>
</LineComponent>
<LineComponent>
<Adjustment Type="Deduction" Category="Discount" SubCategory="D240">
<Description>Freight Discount</Description>
<Value>-55.00</Value>
</Adjustment>
</LineComponent>
<LineComponent>
<Adjustment Type="Addition" Category="Premium" SubCategory="H340">
<Description>EPA Tax</Description>
<Value>2.86</Value>
</Adjustment>
</LineComponent>
<LineComponent>
<Adjustment Type="Addition" Category="Premium" SubCategory="H340">
<Description>EPA Tax</Description>
<Value>20.00</Value>
</Adjustment>
</LineComponent>
I need to output...
<Segment id="SAC">
<Record id="SAC">
<Field id="248">C</Field>
<Field id="1300">D240</Field>
<Field id="610">1000</Field>
<Field id="331">06</Field>
<Field id="352">Freight</Field>
</Record>
</Segment>
<Segment id="SAC">
<Record id="SAC">
<Field id="248">A</Field>
<Field id="1300">D240</Field>
<Field id="610">5500</Field>
<Field id="331">06</Field>
<Field id="352">Freight Discount</Field>
</Record>
</Segment>
<Segment id="SAC">
<Record id="SAC">
<Field id="248">C</Field>
<Field id="1300">H340</Field>
<Field id="610">2286</Field>
<Field id="331">06</Field>
<Field id="352">EPA Tax</Field>
</Record>
</Segment>
...but I am getting this output incorrectly (note concatenation of values)...
<Segment id="SAC">
<Record id="SAC">
<Field id="248">C</Field>
<Field id="1300">D240</Field>
<Field id="610">1000</Field>
<Field id="331">06</Field>
<Field id="352">Freight</Field>
</Record>
</Segment>
<Segment id="SAC">
<Record id="SAC">
<Field id="248">A</Field>
<Field id="1300">D240</Field>
<Field id="610">5500</Field>
<Field id="331">06</Field>
<Field id="352">Freight Discount</Field>
</Record>
</Segment>
<Segment id="SAC">
<Record id="SAC">
<Field id="248">CC</Field>
<Field id="1300">H340H340</Field>
<Field id="610">2862000</Field>
<Field id="331">06</Field>
<Field id="352">EPA TaxEPATax</Field>
</Record>
</Segment>
This is my code at present that is not working. I have two templates...
One isolates the input segments that have unique 'Descriptions' and outputs them individually (that part works).
The other (failing one) is where I am trying to roll-up/combine the input of matching 'Description'; and output their identical SubCategory ("H340"), Description ("EPA Tax"), "C" values, and sum the Value ("2.86" & "20.00").
Note: for the sum of the Value part, I remove the decimal (so 2.86 + 20.00 = 22.86 becomes 2286 in final output.)
<xsl:template name="SAC">
<!-- Service, Promotion, Allowance, or Charge Information -->
<!-- Output Unique Descriptions Part-->
<xsl:for-each
select="
//LineComponent/Adjustment[#SubCategory]/Description[not(. = preceding::LineComponent/Adjustment[#SubCategory]/Description)
and not(. = following::LineComponent/Adjustment[#SubCategory]/Description)]">
<Segment id="SAC">
<!-- Service, Promotion, Allowance, or Charge Information -->
<Record id="SAC">
<!-- Allowance or Charge Indicator -->
<Field id="248">
<xsl:choose>
<xsl:when test="../#Type = 'Addition'">
<!-- 'C' = Charge -->
<xsl:text>C</xsl:text>
</xsl:when>
<xsl:when test="../#Type = 'Deduction'">
<!-- 'A' = Allowance -->
<xsl:text>A</xsl:text>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</Field>
<!-- Service, Promotion, Allowance, or Charge Code (Including Taxes) -->
<Field id="1300">
<xsl:value-of select="../#SubCategory"/>
</Field>
<!-- Amount -->
<Field id="610">
<xsl:value-of select="translate(../Value, '.-+', '')"/>
</Field>
<!-- Allowance/Charge Percent Qualifier -->
<!--<Field id="378">
<!-\- Hard-Coded value 'Z' = Mutually Defined -\->
<xsl:text>Z</xsl:text>
</Field>-->
<!-- Allowance or Charge Method of Handling Code -->
<Field id="331">
<!-- Hard-Coded value '06' = Charge to be Paid by Customer -->
<xsl:text>06</xsl:text>
</Field>
<!-- Description -->
<Field id="352">
<xsl:value-of select="../Description"/>
</Field>
</Record>
</Segment>
</xsl:for-each>
<!-- Combine Common Descriptions Part-->
<xsl:variable name="ACIndicator">
<xsl:for-each
select="
//LineComponent/Adjustment[#SubCategory]/Description[(. = preceding::LineComponent/Adjustment[#SubCategory]/Description)
or (. = following::LineComponent/Adjustment[#SubCategory]/Description)]">
<xsl:choose>
<xsl:when test="../#Type = 'Addition'">
<!-- 'C' = Charge -->
<xsl:text>C</xsl:text>
</xsl:when>
<xsl:when test="../#Type = 'Deduction'">
<!-- 'A' = Allowance -->
<xsl:text>A</xsl:text>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="ACSubCategory">
<xsl:for-each
select="
//LineComponent/Adjustment[#SubCategory]/Description[(. = preceding::LineComponent/Adjustment[#SubCategory]/Description)
or (. = following::LineComponent/Adjustment[#SubCategory]/Description)]">
<xsl:value-of select="../#SubCategory"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="ACTotalValue">
<xsl:for-each
select="
//LineComponent/Adjustment[#SubCategory]/Description[(. = preceding::LineComponent/Adjustment[#SubCategory]/Description)
or (. = following::LineComponent/Adjustment[#SubCategory]/Description)]">
<xsl:value-of select="../Value"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="ACDescription">
<xsl:for-each
select="
//LineComponent/Adjustment[#SubCategory]/Description[(. = preceding::LineComponent/Adjustment[#SubCategory]/Description)
or (. = following::LineComponent/Adjustment[#SubCategory]/Description)]">
<xsl:value-of
select="."
/>
</xsl:for-each>
</xsl:variable>
<Segment id="SAC">
<!-- Service, Promotion, Allowance, or Charge Information -->
<Record id="SAC">
<!-- Allowance or Charge Indicator -->
<Field id="248">
<xsl:value-of
select="$ACIndicator"
/>
</Field>
<!-- Service, Promotion, Allowance, or Charge Code (Including Taxes) -->
<Field id="1300">
<xsl:value-of select="$ACSubCategory"/>
</Field>
<!-- Amount -->
<Field id="610">
<xsl:value-of select="translate($ACTotalValue, '.-+', '')"/>
</Field>
<!-- Allowance or Charge Method of Handling Code -->
<Field id="331">
<!-- Hard-Coded value '06' = Charge to be Paid by Customer -->
<xsl:text>06</xsl:text>
</Field>
<!-- Description -->
<Field id="352">
<xsl:value-of select="$ACDescription"/>
</Field>
</Record>
</Segment>
</xsl:template>
Can use xsl:key and generate-id() to select unique result grouping by composite keys.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="adjustmentDistinct" match="Adjustment" use="concat(#Type, '+', #Category, '+', #SubCategory)"/>
<xsl:template name="SAC" match="/">
<xsl:for-each select=
"//Adjustment[generate-id()
=
generate-id(key('adjustmentDistinct',
concat(#Type, '+', #Category, '+', #SubCategory)
)[1]
)
]
">
<xsl:variable name="vkeyGroup" select=
"key('adjustmentDistinct', concat(#Type, '+', #Category, '+', #SubCategory))"/>
<Segment id="SAC">
<!-- Service, Promotion, Allowance, or Charge Information -->
<Record id="SAC">
<!-- Allowance or Charge Indicator -->
<Field id="248">
<xsl:choose>
<xsl:when test="#Type = 'Addition'">
<!-- 'C' = Charge -->
C
</xsl:when>
<xsl:when test="#Type = 'Deduction'">
<!-- 'A' = Allowance -->
A
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</Field>
<!-- Service, Promotion, Allowance, or Charge Code (Including Taxes) -->
<Field id="1300">
<xsl:value-of select="#SubCategory"/>
</Field>
<!-- Amount -->
<Field id="610">
<xsl:variable name="vSum" select="format-number(sum($vkeyGroup/Value), '#.00')" />
<xsl:value-of select="translate($vSum, '.-+', '')"/>
</Field>
<!-- Allowance or Charge Method of Handling Code -->
<Field id="331">
<!-- Hard-Coded value '06' = Charge to be Paid by Customer -->
<xsl:text>06</xsl:text>
</Field>
<!-- Description -->
<Field id="352">
<xsl:value-of select="Description"/>
</Field>
</Record>
</Segment>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Match in XSLT by solr

I have a problem with field of solr. when multiple nodes does not fit, and it shows empty field.
<field name="specs"/>
the xml original:
<?xml version="1.0" encoding="UTF-8"?>
<tire xmlns="http://schema.grabber" xmlns:x="http://www.w3.org/1999/xhtml"
tire-type="2" product-type="tire" id="102694" trademark="dunlop"
season="3" width="130" height="70" wheels="12" load="62" speed="l"
host="norauto" model="d207" hostDetailId="102694" hostDbID="6">
<url>product/_102694.html</url>
<price>49.95</price>
<ecorate>1.15</ecorate>
<currency>€</currency>
<vat>true</vat>
<img>images_produits/650x650/dunlop-d207-runscoot.jpg</img>
<content>DUNLOP D207 RUNSCOOT</content>
<specs>
<spec name="b_xl">0</spec>
</specs>
</tire>
Transformation XSLT at XML solr, this is xslt of solr:
<xsl:template match="/">
<docs>
<xsl:apply-templates select="cb:tire|cb:products" />
</docs>
</xsl:template>
<xsl:template match="cb:tire">
<doc>
<xsl:apply-templates select="#*|*" />
</doc>
</xsl:template>
<xsl:template match="cb:products">
<xsl:apply-templates select="#*|*" />
</xsl:template>
<xsl:template match="*/*[#name and not(parent::cb:products)]">
<xsl:call-template name="field">
<xsl:with-param name="name" select="concat(name(),'_',#name)"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="*/*[not(#name) and not(parent::cb:products)]">
<xsl:call-template name="field"/>
</xsl:teplate>
<xsl:template match="*[parent::cb:products]">
<xsl:choose>
<xsl:when test="not(text())">
<doc>
<xsl:apply-templates select="*|#*"/>
</doc>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="field"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*|#*">
<xsl:call-template name="field">
<xsl:with-param name="value" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="field">
<xsl:param name="name" select="name()" />
<xsl:param name="value" select="text()" />
<field name="{translate(lower-case($name),' ','_')}">
<xsl:value-of select="$value" />
</field>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
The problem is the element <specs><spec name="b_xl">0</spec></specs>, the field is empty, the result not correct.
This is result XML:
<docs>
<doc>
<field name="tire-type">1</field>
<field name="product-type">tire</field>
<field name="season">1</field>
<field name="id">135-80-r13-70-t-kingstar-sk70</field>
<field name="trademark">kingstar</field>
<field name="model">sk70</field>
<field name="width">135</field>
<field name="height">80</field>
<field name="wheels">13</field>
<field name="load">70</field>
<field name="speed">t</field>
<field name="host">tires</field>
<field name="hostdetailid">135-80-r13-70-t-kingstar-sk70</field>
<field name="hostdbid">1000</field>
<field name="url">135-80-r13-70-t-kingstar-sk70.html</field>
<field name="price">29.73</field>
<field name="currency">€</field>
<field name="vat">true</field>
<field name="img">media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/0/1/0181050080001.png</field>
<field name="content">135/80 R13 70 T KINGSTAR SK70</field>
<field name="specs" />
</doc>
</docs>
I need to display the contents of the element if it contains specs.
To handle the children of specs as field you may add a template like this:
<xsl:template match="cb:specs" priority="1">
<xsl:apply-templates />
</xsl:template>
Which will generate following field:
<field name="spec_b_xl">0</field>
I do not know if this is as expected, because you didn't tell us who the output for specs should look like.

extract name of atribute of class

how show title attribute?
I would like to extract data from the #name.
<specs>
<spec name="b_homologation">1</spec>
<spec name="s_homologation_type">mo</spec>
<spec name="b_xl">0</spec>
<spec name="b_runflat">0</spec>
<spec name="s_consumption">e</spec>
<spec name="i_noise">72</spec>
<spec name="s_grip">c</spec>
</specs>
the result has to be:
<field name="b_homologation">1</field>
<field name="s_homologation_type">mo</field>
...
Thanks.
edit:
<xsl:template match="*|#*">
<xsl:call-template name="field">
<xsl:with-param name="value" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="field">
<xsl:param name="name" select="name()" />
<xsl:param name="value" select="text()" />
<field name="{$name}">
<xsl:value-of select="$value" />
</field>
</xsl:template>
And result is(not correct):
<field name="specs">1mo00e72c</field>
As I suggested in my comment, there's no need to mess around with named templates and parameters here, it's just a plain identity transform with tweaks:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- copy input to output verbatim ... -->
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#*|node()" /></xsl:copy>
</xsl:template>
<!-- ... except spec elements, whose name changes to field -->
<xsl:template match="spec">
<field><xsl:apply-templates select="#*|node()" /></field>
</xsl:template>
</xsl:stylesheet>
This will produce
<specs>
<field name="b_homologation">1</field>
<field name="s_homologation_type">mo</field>
<field name="b_xl">0</field>
<field name="b_runflat">0</field>
<field name="s_consumption">e</field>
<field name="i_noise">72</field>
<field name="s_grip">c</field>
</specs>
You can use the same trick if you want to rename the root specs element to something like fields, but you can't leave it out completely if you want your output to be well-formed XML.
something like this? Didn't test it, can include some mini-bugs :)
<xsl:template match="spec" >
<xsl:call-template name="outputToXml" >
<xsl:with-param name="name" select="#name" />
<xsl:with-param name="value" select="." />
</xsl:call-template>
</xsl:template>
<xsl:template name="outputToXml" >
<xsl:param name="name" />
<xsl:param name="value" />
<xsl:text><field name="</xsl:text>
<xsl:value-of select="$name" />
<xsl:text>"></xsl:text>
<xsl:value-of select="$value" />
<xsl:text></field></xsl:text>
</xsl:template>

How to create an attribute node and attach it to output node..?

I'm not able to figure out a way to attach an attribute node to output node in below scenario..
input xml:
<record>
<user>
<field name="LastName">user33</field>
<field name="FirstName">user33</field>
<field name="Title"/>
<field name="Email">user33#gmail.com</field>
<field name="WorkPhone"/>
<field name="Fax"/>
<field name="Description">new user</field>
<field name="Group Member"> group1</field>
</user>
</record>
Expected output:
<add class="user" id-val="user33 user33" >
<add-value attr="LastName">
<value type="string">user33</value>
</add-attr>
<add-value attr="FirstName">
<value type="string">user33</value>
</add-value>
<add-value attr="Email">
<value type="string">user33#gamil.com</value>
</add-value>
<add-value attr="Description">
<value type="string">new user</value>
</add-value>
</add>
this is the snippet of xslt that i have so far.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="lessThan" select="'<'"/>
<xsl:variable name="GreaterThan" select="'>'"/>
<xsl:template match="user">
<xsl:variable name="temp1" select="concat(field[#name=$srcdn-field-name1],' ')"/>
<xsl:variable name="temp2" select="concat($temp1,field[#name=$srcdn-field-name2])"/>
<xsl:variable name="src" select="translate($temp2,'+=,.\','-----')"/>
<xsl:value-of disable-output-escaping="yes" select="$lessThan"/>
<xsl:text>add</xsl:text>
<xsl:value-of disable-output-escaping="yes" select="$GreaterThan"/>
<!-- it is required to add attribute id-val to element <add> with value of $src-->
<xsl:for-each select="field[string()]">
<xsl:variable name="fieldValue" select="normalize-space(.)"/>
<xsl:choose>
<xsl:when test="#name !='Group Member'">
<add-value attr="{#name}">
<value type="string">
<xsl:value-of select="$fieldValue"/>
</value>
</add-value>
</xsl:when>
<xsl:otherwise>
<xsl:value-of disable-output-escaping="yes" select="$lessThan"/>
<xsl:text>/add</xsl:text>
<xsl:value-of disable-output-escaping="yes" select="$GreaterThan"/>
<!--perform some other operations-->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Now my requirement is to have id-val and class as attributes of <add>.. In this context the <xsl:attribute> isn't working. What changes do i need to make to my xslt.?
You can't add an attribute to something that's not an element. That's one of the many reasons not to try to manually construct start and end tags. Try this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="user">
<xsl:variable name="temp1" select="concat(field[#name=$srcdn-field-name1],' ')"/>
<xsl:variable name="temp2" select="concat($temp1,field[#name=$srcdn-field-name2])"/>
<xsl:variable name="src" select="translate($temp2,'+=,.\','-----')"/>
<add class="user" id-val="{$src}">
<!-- it is required to add attribute id-val to element <add> with value of $src-->
<xsl:for-each select="field[string()]
[not((. | preceding-sibling::field)
[#name = 'Group Member'])]">
<add-value attr="{#name}">
<value type="string">
<xsl:value-of select="normalize-space()"/>
</value>
</add-value>
</xsl:for-each>
</add>
</xsl:template>
</xsl:stylesheet>

EXSLT str:replace

Im having issues getting my XML to transform correctly using the EXSLT str:replace template.
Here is my XML:
<XML>
<Item>
<Field>
<Name>ID</Name>
<Value>98765</Value>
</Field>
<Field>
<Name>ParentID</Name>
<Value>10002</Value>
</Field>
<Field>
<Name>Type</Name>
<Value>content</Value>
</Field>
<Field>
<Name>Name</Name>
<Value>TestAPI Course</Value>
</Field>
<Field>
<Name>URL</Name>
<Value></Value>
</Field>
<Field>
<Name>Description</Name>
<Value>a description</Value>
</Field>
<Field>
<Name>DateBegin</Name>
<Value>2012-04-04T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateEnd</Name>
<Value>2012-04-04T00:00:00.000-08:00</Value>
</Field>
<Field>
<Name>DateCreated</Name>
<Value>2012-04-03T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateModified</Name>
<Value>2012-04-04T00:00:00.000-06:00</Value>
</Field>
</Item>
Here is my XSL:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" extension-element-prefixes="str" version="1.0">
<xsl:import href="C:\inetpub\wwwroot\LMSConnector\LMS\XSL\str.xsl"/>
<xsl:template match="/Items">
<xsl:call-template name="str:replace">
<xsl:with-param name="string" select="Field/Name"/>
<xsl:with-param name="search" select="ID"/>
<xsl:with-param name="replace" select="sco-id"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
My problem is that I just get a XML document header and nothing else, but nothing else? I dont think I am far off a working solution and the problems probably lie in the values i am setting for the "match" parameter on the template, and the select parameters within the call-template with-param nodes.
Any help would be appreciated.
Mike
You are trying to match <xsl:template match="/Items">, however your XML contains <Item> elements, not <Items>.
EDIT
Is this what you are trying to do?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
<xsl:import href="http://delicious-library-export.googlecode.com/svn/trunk/str/str.xsl"/>
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/Item/Field/Name/text()">
<xsl:call-template name="str:replace">
<xsl:with-param name="string" select="."/>
<xsl:with-param name="search" select="'ID'"/>
<xsl:with-param name="replace" select="'sco-id'"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Result:
<?xml version="1.0" encoding="utf-8"?>
<Item>
<Field>
<Name>sco-id</Name>
<Value>98765</Value>
</Field>
<Field>
<Name>Parentsco-id</Name>
<Value>10002</Value>
</Field>
<Field>
<Name>Type</Name>
<Value>content</Value>
</Field>
<Field>
<Name>Name</Name>
<Value>TestAPI Course</Value>
</Field>
<Field>
<Name>URL</Name>
<Value/>
</Field>
<Field>
<Name>Description</Name>
<Value>a description</Value>
</Field>
<Field>
<Name>DateBegin</Name>
<Value>2012-04-04T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateEnd</Name>
<Value>2012-04-04T00:00:00.000-08:00</Value>
</Field>
<Field>
<Name>DateCreated</Name>
<Value>2012-04-03T00:00:00.000-07:00</Value>
</Field>
<Field>
<Name>DateModified</Name>
<Value>2012-04-04T00:00:00.000-06:00</Value>
</Field>
</Item>