user1997340
user1997340

Reputation: 45

How to add to all the childs of a node the attributes of another node in XSLT?

This is my Xml File

 <?xml version="1.0" encoding="UTF-8"?>
    <records>
    <REC>
        <ID>000173379701048</ID>
        <static_data>
          <summary>
            <names count="2">
              <name>
                <display_name>TT</display_name>
                <full_name>TT</full_name>
              </name>
              <name>
                <display_name>NM</display_name>
                <full_name>NM</full_name>
              </name>
            </names>
          </summary>
     </static_data>
    <REC>
    </records>

So far with this XSLT code i am getting the below result

<?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:for-each select="/records/REC">
             <xsl:text>&#34;</xsl:text>
             <xsl:value-of select="ID" />
             <xsl:text>&#34;</xsl:text>
             <xsl:value-of select ="','"/>

     <xsl:for-each select="static_data/summary/names/name">
                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select="display_name" />
                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select ="','"/>

                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select="full_name" />
                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select ="','"/>
       </xsl:for-each>

       </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

The result that I am having in a csv file is

 "000173379701048", "TT", "TT",
 "NM", "NM",

what I expect to get is

"000173379701048", "TT", "TT",
"000173379701048", "NM", "NM",

Please any advice is welcomed since I am new with xslt :)

Upvotes: 1

Views: 41

Answers (3)

nwellnhof
nwellnhof

Reputation: 33638

The trick is to write a template matching the name nodes and use the parent axis to get the ID. Other improvements:

  • When creating text files, make sure to set the output method to text.
  • You can avoid some repetition by adding an extra template to quote the CSV values. Note the use of the mode attribute.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
    <xsl:apply-templates select="records/REC/static_data/summary/names/name"/>
</xsl:template>

<xsl:template match="name">
    <xsl:apply-templates select="../../../../ID" mode="quote"/>
    <xsl:text>,</xsl:text>
    <xsl:apply-templates select="display_name" mode="quote"/>
    <xsl:text>,</xsl:text>
    <xsl:apply-templates select="full_name" mode="quote"/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="*" mode="quote">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>"</xsl:text>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

Ian Roberts
Ian Roberts

Reputation: 122374

Instead of just displaying the record ID once in the outer for-each, you need to move that code into the inner for-each. Try this - note I've also simplified all the xsl:text and xsl:value-of parts into a single concat:

<?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:for-each select="/records/REC">
      <xsl:variable name="id" select="ID" /><!-- question said UID but input has ID -->
      <xsl:for-each select="static_data/summary/names/name">
         <xsl:value-of select="concat(
             '&quot;', $id, '&quot;,',
             '&quot;', display_name, '&quot;,',
             '&quot;', full_name, '&quot;,')"/>
         </xsl:for-each>
     </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

(though this will print everything on one long line, presumably you actually want to put things on separate rows, in which case replace the last '&quot;,' with '&quot;&#10;').

Upvotes: 1

Linga Murthy C S
Linga Murthy C S

Reputation: 5432

Try this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/records/REC">
        <xsl:apply-templates select="static_data/summary/names/name"/>
    </xsl:template>
    <xsl:template match="name">
        <xsl:text>"</xsl:text>
        <xsl:value-of select="../../../../ID" />
        <xsl:text>"</xsl:text>
        <xsl:text>,</xsl:text>
        <xsl:text>"</xsl:text>
        <xsl:value-of select="display_name" />
        <xsl:text>",</xsl:text>
        <xsl:text>"</xsl:text>
        <xsl:value-of select="full_name" />
        <xsl:text>",</xsl:text>
        <xsl:if test="position() != last()">
            <xsl:text>&#xa;</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Related Questions