0

In the below XSLT I'm checking the following

  1. If element is null then replace then replace it with the value of another element.
  2. If attribute of that element is null then replace it with constant value.

1 is working, however 2 is not.

For 2 I have tried two things:

First, using the xsl:if condition didn't work. It is adding a new node with the same node name instead of inserting a value to the attribute.

Second I have tried to use the template. That didn't work either. It is completely eliminating the node and adding the attribute to the parent with the value.

Also, is it possible to do it differently or a better way.

XSLT

  <xsl:template match="//ns0:Cedent/ns0:Party/ns0:Id">
    <xsl:if test="//ns0:Cedent/ns0:Party/ns0:Id = ''">
      <xsl:copy>
        <xsl:value-of select="//ns0:Broker/ns0:Party/ns0:Id"/>
      </xsl:copy>
    </xsl:if>
    <!--<xsl:if test="//ns0:Cedent/ns0:Party/ns0:Id[@Agency = '']">
      <xsl:copy>
        <xsl:attribute name="Agency">Legacy</xsl:attribute>
        <xsl:value-of select="'Legacy'"/>
      </xsl:copy>
    </xsl:if>-->
  </xsl:template>

  <xsl:template match="//ns0:Cedent/ns0:Party/ns0:Id[@Agency = '']">
    <xsl:attribute name="Agency">Legacy</xsl:attribute>
  </xsl:template>

input

<ns0:Testing>
  <ns0:Cedent>
    <ns0:Party>
      <ns0:Id Agency=""></ns0:Id>
      <ns0:Name>Canada</ns0:Name>
    </ns0:Party>
  </ns0:Cedent>
  <ns0:Broker>
    <ns0:Party>
      <ns0:Id Agency="Legacy">292320710</ns0:Id>
      <ns0:Name>Spain</ns0:Name>
    </ns0:Party>
  </ns0:Broker>
</ns0:Testing>

output

<ns0:Testing>
    <ns0:Cedent>
      <ns0:Party>
        <ns0:Id Agency="Legacy">292320710</ns0:Id>
        <ns0:Name>Canada</ns0:Name>
      </ns0:Party>
    </ns0:Cedent>
</ns0:Testing>

1 Answer 1

1
<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ns0="some_namespace_uri"
>
  <xsl:output indent="yes" />

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

  <xsl:template match="ns0:Cedent/ns0:Party/ns0:Id[. = '']">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="
        ../../following-sibling::ns0:Broker[1]/ns0:Party/ns0:Id/node()
      " />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ns0:Cedent/ns0:Party/ns0:Id/@Agency[. = '']">
    <xsl:attribute name="Agency">Legacy</xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Gives you

<Testing xmlns="some_namespace_uri">
  <Cedent>
    <Party>
      <Id Agency="Legacy">292320710</Id>
      <Name>Canada</Name>
    </Party>
  </Cedent>
  <Broker>
    <Party>
      <Id Agency="Legacy">292320710</Id>
      <Name>Spain</Name>
    </Party>
  </Broker>
</Testing>

Notes:

  • if you don't want the <Broker> element in the output at all, add an empty template:

    <xsl:template match="ns0:Broker" />
    
  • Match expressions in templates do not need to start at the root node.

  • Stylesheets whose job it is to copy the input with only a few changes, like this one, should always start with the identity template.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.