Guilherme Schults
Guilherme Schults

Reputation: 53

Empty tag xml - add value from another tag with xslt

I'm saw an example from here How to Insert an XML tag after a particular tag using XSLT? but this is not exactly my problem.

I have a xml and some of it's tag is missing value, example:

<row>
    <title>The Outsider</title>
    <year>2018</year>
    <actors></actors> <!-- empty tag: add value "unknown" -->
    <actors>Tadanobu Asano</actors>
    <actors>Kippei Shîna</actors>
    <actors>Shioli Kutsuna</actors>
    <actors>Emile Hirsch</actors>
    <actors>Ray Nicholson</actors>
    <actors>Rory Cochrane</actors>
    <actors>Nao Ohmori</actors>
    <actors>Min Tanaka</actors>
    <actors>Masaki Miura</actors>
    <actors>Shun Sugata</actors>
    <actors>Hiroya Shimizu</actors>
    <actors>Hiro</actors>
    <actors>Young Dais</actors>
    <actors>Gô Jibiki</actors>
    <genre>Action</genre>
    <genre>Crime</genre>
    <genre>Drama</genre>
    <genre>Thriller</genre>
    <description/>      <!-- here is missing <description> -->
</row>

What I want is to add the value to the tag.

Desirable output:

 <row>
        <title>The Outsider</title>
        <year>2018</year>
        <actors>Unknown</actors> <!-- add word "unknown" if tag is empty -->
        <actors>Tadanobu Asano</actors>
        <actors>Kippei Shîna</actors>
        <actors>Shioli Kutsuna</actors>
        <actors>Emile Hirsch</actors>
        <actors>Ray Nicholson</actors>
        <actors>Rory Cochrane</actors>
        <actors>Nao Ohmori</actors>
        <actors>Min Tanaka</actors>
        <actors>Masaki Miura</actors>
        <actors>Shun Sugata</actors>
        <actors>Hiroya Shimizu</actors>
        <actors>Hiro</actors>
        <actors>Young Dais</actors>
        <actors>Gô Jibiki</actors>
        <genre>Action</genre>
        <genre>Crime</genre>
        <genre>Drama</genre>
        <genre>Thriller</genre>
        <description>The Outsider<description/>  <!-- complete <description> with <title> value -->
    </row>

So far, I tried with this:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

   <xsl:template match="node()|@*" name="ident">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>
 
      <xsl:template match="row[not(description)]">
        <xsl:copy>
                <xsl:apply-templates select="genre"/>
                    <description>
                      <xsl:value-of select="./title" />
                    </description>
                <xsl:apply-templates select="*[not(self::genre)]"/>
          </xsl:copy>
        </xsl:template>


</xsl:transform>

But I'm not getting what I want in the output xml. Can you help me? Thank you.

Upvotes: 0

Views: 180

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117102

Your title says "missing tag" - but your example shows empty actor and description elements, not missing ones. If that's the only situation you need to handle, you could do simply:

XSLT 1.0

<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"/>

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

<xsl:template match="actors[not(text())]">
    <xsl:copy>Unknown</xsl:copy>
</xsl:template>

<xsl:template match="description[not(text())]">
    <xsl:copy>
        <xsl:value-of select="../title" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions