Carla
Carla

Reputation: 63

Copy value of element A if element B is missing

I have this XML:

<wd:Report_Data xmlns:wd="urn:com.workday.report/INT005_">
<wd:Report_Entry>
    <wd:AREA>Comp1</wd:AREA>
    <wd:TOP>Dept1</wd:TOP>
    <wd:NUMBER>1234567890</wd:NUMBER>
</wd:Report_Entry>
<wd:Report_Entry>
    <wd:AREA>Comp2</wd:AREA>
</wd:Report_Entry>
</wd:Report_Data>

And XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="wd" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:wd="urn:com.workday.report/INT005_">

<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*" />

<xsl:template match="wd:Report_Data">
 <wd:Report_Data>
   <xsl:for-each select="wd:Report_Entry">
    <wd:Report_Entry>
      <wd:AREA><xsl:value-of select="wd:AREA"/></wd:AREA>
      <wd:TOP>
         <xsl:choose>
            <xsl:when test="wd:TOP=''">
                <xsl:value-of select="wd:AREA"/>
            </xsl:when>
            <xsl:otherwise><xsl:value-of select="wd:TOP"/></xsl:otherwise>
         </xsl:choose>
      </wd:TOP>
      <wd:NUMBER><xsl:value-of select="wd:NUMBER"/></wd:NUMBER>
    </wd:Report_Entry>
   </xsl:for-each>
  </wd:Report_Data>
</xsl:template> 
</xsl:stylesheet>

The conditions are: 1.When there is no wd:NUMBER, element wd:NUMBER should remain in the output file (correctly set up) 2.When wd:TOP is not empty, just copy the value (correctly set up) 3.When wd:TOP is not existing, copy the value of wd:AREA (this is the issue)

so desired output is:

<?xml version="1.0" encoding="UTF-8"?>
<wd:Report_Data xmlns:wd="urn:com.workday.report/INT005_">
  <wd:Report_Entry>
  <wd:AREA>Comp1</wd:AREA>
  <wd:TOP>Dept1</wd:TOP>
  <wd:NUMBER>1234567890</wd:NUMBER>
 </wd:Report_Entry>
 <wd:Report_Entry>
  <wd:AREA>Comp2</wd:AREA>
  <wd:TOP>Comp2</wd:TOP>
  <wd:NUMBER/>
 </wd:Report_Entry>
</wd:Report_Data>

What should I do to make condition number 3? Thanks in advance!

Upvotes: 1

Views: 31

Answers (1)

StuartLC
StuartLC

Reputation: 107267

Detecting for the presence of a node altogether is simply:

<xsl:if test="Node">

and similarly the test for an absence of a node is:

<xsl:if test="not(Node)">

I think what you want for condition 3 is

<xsl:if test="not(wd:TOP)">
   <xsl:value-of select="wd:AREA"/>
</xsl:if>

It looks like you want the same outcome for both empty or missing wd:TOP, so:

 <wd:TOP>
     <xsl:choose>
        <xsl:when test="wd:TOP='' or not(wd:TOP)">
            <xsl:value-of select="wd:AREA"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="wd:TOP"/>
        </xsl:otherwise>
     </xsl:choose>
  </wd:TOP>

Commonly, there's one other condition you may need to test for, viz nil, which would require a check for:

wd:TOP/@xsi:nil = 'true'

Upvotes: 1

Related Questions