-1

I was looking to get the XPath to get the value of ad:pd element. I have tried all the ways possible in the XPath to get the value, but none of then worked.

<?xml version="1.0" encoding="UTF-8"?>
<ad:sgRes
    xmlns:ad="http://www.thehtf.co.uk/Data/V1.0">
    <ad:Msg>
        <ad:cpn>
            <ad:ist>
                <ad:tm>
                    <ad:pd>12016</ad:pd>
                </ad:tm>
            </ad:ist>
        </ad:cpn>
    </ad:Msg>
</ad:sgRes>

The XPATH I used was: //pd //*:pd ad:sgRes/ad:Msg/ad:cpn/ad:ist/ad:tm/ad:pd //ad:tm/*:pd but none of them worked. Also tried using exclude-result-prefixes="ad" with no success. I have gone through few posts here but none of them worked. That's why posting my question here. Probably a very easy things for you guys to answer. But definitely I am missing something here.

Adding my XSLT code here. None of the solution mentioned in the comments worked for me. What am I missing here:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:ad="http://www.thehtf.co.uk/Data/V1.0" 
  xmlns:dp="http://www.datapower.com/extensions" 
  xmlns:func="http://exslt.org/functions" 
  xmlns:apim="http://www.ibm.com/apimanagement"
extension-element-prefixes="dp func apim ad" exclude-result-prefixes="dp">

  <xsl:import href="local:///isp/policy/apim.custom.xsl"/>

  <xsl:template match="/">
    <xsl:variable name="payload" select="apim:getVariable('Output.body')" />
    <xsl:variable name="pdCode" select="$payload//*[local-name()='pd']"/>
     </xsl:variable>

    <xsl:choose>
      
       <xsl:when test="$pdCode='66'">
        <xsl:call-template name="apim:setVariable">
          <xsl:with-param name="varName" select="'Check'"/>
          <xsl:with-param name="value" select="'True'"/>
        </xsl:call-template>
      </xsl:when>
      
      <xsl:when test="$pdCode='31'">
        <xsl:call-template name="apim:setVariable">
          <xsl:with-param name="varName" select="'Check'"/>
          <xsl:with-param name="value" select="'False'"/>
        </xsl:call-template>
      </xsl:when>

      <xsl:otherwise>
        <xsl:call-template name="apim:setVariable">
          <xsl:with-param name="varName" select="'Check'"/>
          <xsl:with-param name="value" select="'UnknownError'"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

apim.custom.xsl

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  xmlns:apim="http://www.ibm.com/apimanagement"
  xmlns:webapi="http://www.ibm.com/apimanagement"
  xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"
  extension-element-prefixes="dp func"
  exclude-result-prefixes="dp func apim webapi json">

  <xsl:import href="local:///isp/error_template.xsl" dp:ignore-multiple="yes"/>
  <xsl:import href="apim.context.xsl" dp:ignore-multiple="yes" />
  <xsl:import href="assembly-util.xsl" dp:ignore-multiple="yes" />
  <xsl:include href="apim.setvariable-impl.xsl" dp:ignore-multiple="yes"/>


  <!--
   ============================================================================================
   ============================================================================================
   -->

  <func:function name="apim:payloadRead">
    <xsl:variable name="gscript" select="'local:///isp/policy/apim.custom.xsl.js'"/>
    <xsl:variable name="input-media" select="dp:variable('var://context/_apimgmt/content-type')" />
    <xsl:variable name="polic-media" select="dp:variable('var://context/_apimgmt/policy-output-mediaType')" />
    <xsl:variable name="usePolicyOutput" select="dp:variable('var://context/_apimgmt/use-policy-output')"/>

    <xsl:if test="$debug1">
      <xsl:message dp:priority="debug">
        <xsl:text>apim:payloadRead: [</xsl:text>
        <xsl:value-of select="$input-media"/>
        <xsl:text>][</xsl:text>
        <xsl:value-of select="$polic-media"/>
        <xsl:text>][</xsl:text>
        <xsl:value-of select="$usePolicyOutput"/>
        <xsl:text>]</xsl:text>
      </xsl:message>
    </xsl:if>
    <!-- -->
    <!-- -->
    <xsl:choose>
      <xsl:when test="webapi:isContentJSON($polic-media) = 'y' or (webapi:isContentJSON($input-media) = 'y' and webapi:isContentXML($polic-media) = 'n')">
        <xsl:variable name="params">
          <parameter name="action">readInputAsJSONX</parameter>
        </xsl:variable>
        <xsl:variable name="result" select="dp:gatewayscript($gscript, ., true(), $params)"/>
        <xsl:variable name="jsonx1" select="$result/gatewayscript/result/text()"/>
        <func:result>
          <xsl:choose>
            <xsl:when test="string-length($jsonx1) &gt; 0">
              <dp:parse select="$jsonx1"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:copy-of select="/.."/>
            </xsl:otherwise>
          </xsl:choose>
        </func:result>
      </xsl:when>
      <!--@@ XML Payload from 'policy-output' -->
      <xsl:when test="webapi:isContentXML($polic-media) = 'y' and $usePolicyOutput = 'true'">
        <func:result>
          <xsl:copy-of select="dp:variable('var://context/policy-output')" />
        </func:result>
      </xsl:when>
      <!--@@ XML Payload from 'INPUT' - first time reading it -->
      <xsl:when test="webapi:isContentXML($input-media) = 'y'">
         <!-- If the original input media is specified, set the output media as that value. This will ensure
         that the policy does not change the content type from text/xml to application/xml for example. If it
         is not specified (the original content type is the name of the variable or is empty, it will default to
         input-media (i.e. application/xml). -->
         <xsl:variable name="original-input-media">
           <xsl:choose>
             <xsl:when test="dp:responding() = true()">
               <xsl:variable name="temp" select="normalize-space(dp:variable('var://service/original-response-content-type'))" />
               <xsl:choose>
                 <xsl:when test="not($temp = 'var://service/original-response-content-type')">
                   <xsl:value-of select="$temp" />
                 </xsl:when>
                 <xsl:otherwise>
                   <xsl:value-of select="/.." />
                 </xsl:otherwise>
               </xsl:choose>
             </xsl:when>
             <xsl:otherwise>
               <xsl:variable name="temp" select="normalize-space(dp:variable('var://service/original-content-type'))" />
               <xsl:choose>
                 <xsl:when test="not($temp = 'var://service/original-content-type')">
                   <xsl:value-of select="$temp" />
                 </xsl:when>
                 <xsl:otherwise>
                   <xsl:value-of select="/.." />
                 </xsl:otherwise>
               </xsl:choose>
             </xsl:otherwise>
           </xsl:choose>
         </xsl:variable>
         <xsl:choose>
           <xsl:when test="string($original-input-media)">
             <dp:set-variable name="'var://context/_apimgmt/policy-output-mediaType'" value="string($original-input-media)" />
           </xsl:when>
           <xsl:otherwise>
             <dp:set-variable name="'var://context/_apimgmt/policy-output-mediaType'" value="string($input-media)" />
           </xsl:otherwise>
         </xsl:choose>

         <func:result>
           <xsl:copy-of select="dp:variable('var://context/INPUT')" />
         </func:result>
      </xsl:when>
      <!-- -->
      <xsl:otherwise>
      </xsl:otherwise>
    </xsl:choose>
  </func:function>

  <!--
   ============================================================================================
   ============================================================================================
   -->

  <xsl:template name="apim:output">
    <xsl:param name="mediaType" select="''" />

   <xsl:if test="$mediaType != ''">
     <dp:set-variable name="'var://context/_apimgmt/policy-output-mediaType'" value="string($mediaType)" />
   </xsl:if>

   <dp:set-variable name="'var://context/_apimgmt/policy-output-set'" value="'true'"/>
   <dp:set-variable name="'var://context/_apimgmt/content-type-override'" value="''"/>
  </xsl:template>

  <!--
   ============================================================================================
   ============================================================================================
   -->
  <func:function name="apim:payloadType">
   <func:result>
     <xsl:value-of select="dp:variable('var://context/_apimgmt/policy-output-mediaType')" />
   </func:result>
  </func:function>


  <!--
   ============================================================================================
   ============================================================================================
   -->

  <func:function name="apim:policyProperties">
    <xsl:variable name="policy-props" select="webapi:getPolicyDoc()"/>
    <xsl:variable name="processed">
      <xsl:choose>
        <xsl:when test="$policy-props/policy/properties[@array = 'true']">
          <xsl:copy-of select="$policy-props/policy/properties"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="$policy-props/policy/properties" mode="policyproperties"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <func:result>
      <xsl:copy-of select="$processed"/>
    </func:result>

  </func:function>

  <xsl:template match="properties[@name]" mode="policyproperties">
    <xsl:choose>
      <!-- if we have an array, must handle each child array element
           that will have a @name of 0, 1 ... n -->
      <xsl:when test="@array = 'true'">
        <xsl:variable name="arrayName" select="@name" />
        <xsl:for-each select="./properties | ./property">
          <xsl:element name="{$arrayName}">
            <xsl:apply-templates select="@* | node()" mode="policyproperties"/>
          </xsl:element>
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="{@name}">
          <xsl:value-of select="text()"/>
          <xsl:apply-templates select="@* | node()" mode="policyproperties"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

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

  <xsl:template match="property" mode="policyproperties">

    <xsl:choose>
      <xsl:when test="@name = 'scopes'">
        <xsl:element name="scopes">
          <xsl:choose>
            <xsl:when test="@type = 'string'">
              <xsl:choose>
                <xsl:when test="string-length(.) &gt; 0">
                  <xsl:copy-of select="dp:parse(.)"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:copy-of select="/.."/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
              <xsl:copy-of select=".//set"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:element>
      </xsl:when>
      <xsl:when test="starts-with(@name, 'scopes.')">
        <xsl:element name="scope">
          <xsl:attribute name="original"><xsl:value-of select="@name"/></xsl:attribute>
          <xsl:attribute name="desc"><xsl:value-of select="text()"/></xsl:attribute>
          <xsl:value-of select="substring-after(@name, 'scopes.')"/>
        </xsl:element>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="{@name}">
          <xsl:value-of select="text()"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

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



  <!--
   ============================================================================================
   ============================================================================================
   -->

  <!-- deprecated -->
  <func:function name="apim:readContext">
    <func:result>
      <xsl:call-template name="buildContext" />
    </func:result>
  </func:function>

  <func:function name="apim:getContext">
    <xsl:param name="var" />
    <func:result>
      <xsl:value-of select="apim:getContextByVariable($var)" />
    </func:result>
  </func:function>


  <!--
   ============================================================================================
   ============================================================================================
   -->

  <xsl:template name="apim:error">
    <xsl:param name="httpCode" />
    <xsl:param name="httpReasonPhrase" />
    <xsl:param name="errorName" select="'runtime.error'"/>
    <xsl:param name="errorMessage" select="''"/>
    <xsl:param name="ignorecatch" select="'false'"/>

    <xsl:call-template name="error">
      <xsl:with-param name="name" select="$errorName"/>
      <xsl:with-param name="code"   select="$httpCode"/>
      <xsl:with-param name="reason" select="$httpReasonPhrase"/>
      <xsl:with-param name="message" select="$errorMessage"/>
      <xsl:with-param name="ignorecatch" select="$ignorecatch"/>
    </xsl:call-template>
  </xsl:template>

  <!--
  ============================================================================================
  Function to return the exception JSON object as XML so customers don't need to pull the
  context variable directly.
  ============================================================================================
  -->
  <func:function name="apim:getError">

    <xsl:variable name="exception" select="dp:variable('var://context/policy/fw/exception')" />
    <xsl:variable name="result" select="dp:stringToJSONx($exception)"/>
    <func:result>
      <error>
        <name><xsl:value-of select="$result/json:object/*[@name='name']"/></name>
        <message><xsl:value-of select="$result/json:object/*[@name='message']"/></message>
        <policyTitle><xsl:value-of select="$result/json:object/*[@name='policyTitle']"/></policyTitle>
        <status>
          <code><xsl:value-of select="$result/json:object/*[@name='httpCode']"/></code>
          <reason><xsl:value-of select="$result/json:object/*[@name='httpReasonPhrase']"/></reason>
        </status>
      </error>
    </func:result>
  </func:function>

  <!--
  ============================================================================================
  Gateway properties can be set in local:///ext/gateway-properties.xml overridden by an
  API property of the same name.
   - Values must be a string type.
  ============================================================================================
  -->

  <func:function name="apim:getGatewayProperty">
    <xsl:param name="propertyName"/>

    <xsl:variable name="apiProp" select="apim:getApiPropertyValue($propertyName)" />
    <xsl:variable name="result">
      <xsl:choose>
        <xsl:when test="string-length($apiProp) > 0">
           <xsl:value-of select="$apiProp"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:variable name="domain" select="dp:variable('var://service/domain-name')" />
          <xsl:variable name="extVar" select="concat('var://system/_apimgmt/', $domain,'/dpext')" />
          <xsl:value-of select="dp:variable($extVar)//property[@name=$propertyName]"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <func:result>
      <xsl:value-of select="string($result)" />
    </func:result>
  </func:function>

  <!--
  ============================================================================================
  ============================================================================================
  -->

  <func:function name="apim:getApiProperty">
    <xsl:param name="propertyName"/>
    <func:result>
      <xsl:value-of select="apim:getApiPropertyValue($propertyName)" />
    </func:result>
  </func:function>

  <!--
  ============================================================================================
  ============================================================================================
  -->

  <func:function name="apim:getApiProperties">
    <xsl:variable name="policiesXml" select="dp:variable('var://context/policy/fw/input-map')" />
    <xsl:variable name="configProperties">
      <xsl:for-each select="$policiesXml/policies/cfgProperty">
        <xsl:element name="{@name}">
          <xsl:value-of select="apim:getApiPropertyValue(@name,$policiesXml)" />
        </xsl:element>
      </xsl:for-each>
    </xsl:variable>
    <func:result>
      <xsl:copy-of select="$configProperties" />
    </func:result>
  </func:function>


  <!-- ======================================================================= -->
  <xsl:template name="apim:payloadReadOrigin" >
    <xsl:param name="input-media" select="dp:variable('var://context/_apimgmt/content-type')" />
    <xsl:variable name="ruletype" select="dp:variable('var://service/transaction-rule-type')" />
    <xsl:choose>
      <xsl:when test="$input-media = 'application/xml'">
        <xsl:copy-of select="dp:variable('var://context/INPUT')" />
      </xsl:when>
      <xsl:when test="$ruletype = 'request' and $input-media = 'application/json'">
        <xsl:copy-of select="dp:variable('var://context/__JSONASJSONX')" />
      </xsl:when>
      <xsl:when test="$input-media = 'application/json'">
        <xsl:copy-of select="dp:variable('var://context/__JSONASJSONX2')" />
      </xsl:when>
      <xsl:otherwise/>
    </xsl:choose>
  </xsl:template>

  <!-- ======================================================================= -->
  <xsl:template name="apim:setVariable">
    <xsl:param name="varName"/>
    <xsl:param name="value"/>
    <xsl:param name="action" select="'Set'" />

    <xsl:call-template name="apim:setVariableImpl">
      <xsl:with-param name="rawName" select="$varName" />
      <xsl:with-param name="rawValue" select="$value" />
      <xsl:with-param name="action" select="$action" />
    </xsl:call-template>
  </xsl:template>

  <!-- ======================================================================= -->
  <func:function name="apim:getVariable">
    <xsl:param name="varName" />
    <xsl:param name="decode" />
    <xsl:param name="encodePlus" select="'false'"/>

    <func:result select="apim:getVariableImpl($varName, $decode, $encodePlus)" />
  </func:function>

  <!--
   ============================================================================================
   ============================================================================================
   -->

  <func:function name="apim:getRegistry">
    <xsl:param name="name"/>
    <xsl:variable name="servicesXml" select="dp:variable('var://context/_apimgmt/tenant-policy')"/>
    <xsl:variable name="result" select="$servicesXml/registries/ldap[@name = $name]"/>
    <xsl:if test="not($result) and $debug1">
      <xsl:message dp:type="apiconnect" dp:priority="debug">
        <xsl:text>apim:getRegistry(</xsl:text>
        <xsl:value-of select="$name"/>
        <xsl:text>) not found. Known names are: </xsl:text>
        <xsl:for-each select="$servicesXml/registries/ldap">
          <xsl:value-of select="@name"/>
          <xsl:text> </xsl:text>
        </xsl:for-each>
      </xsl:message>
    </xsl:if>
    <func:result>
      <xsl:copy-of select="$result"/>
    </func:result>
  </func:function>


    <!-- ======================================================================= -->
  <func:function name="apim:getTLSProfileObjName">
    <xsl:param name="inputName" />

    <xsl:variable name="params">
      <parameter name="funcName">getTLSProfileObjName</parameter>
      <parameter name="args"><xsl:value-of select="string($inputName)"/></parameter>
    </xsl:variable>

    <func:result>
      <xsl:copy-of select="dp:gatewayscript('local:///isp/policy/xslt-to-js-bridge.js', $params, false())"/>
    </func:result>
  </func:function>

    <!-- ======================================================================= -->
  <func:function name="apim:getManagedObject">
    <xsl:param name="type" /> <!-- Required -->
    <xsl:param name="name" />
<!--    <xsl:param name="version" /> -->
    <xsl:param name="property" />
    <xsl:param name="asFilename" select="'false'"/>
<!--    <xsl:param name="id" /> -->


    <xsl:variable name="params">
      <parameter name="funcName">getManagedObject</parameter>
      <parameter name="args">
          <xsl:text>[{"name":"</xsl:text>
          <xsl:value-of select="string($name)"/>
<!--
          <xsl:text>","version":"</xsl:text>
          <xsl:value-of select="string($version)"/>
          <xsl:text>","id":"</xsl:text>
          <xsl:value-of select="string($id)"/>
-->
          <xsl:text>","property":"</xsl:text>
          <xsl:value-of select="string($property)"/>
          <xsl:text>","asFilename":"</xsl:text>
          <xsl:value-of select="string($asFilename)"/>
          <xsl:text>"},"</xsl:text>
          <xsl:value-of select="string($type)"/>
          <xsl:text>"]</xsl:text>
      </parameter>
    </xsl:variable>

    <func:result>
      <xsl:copy-of select="dp:gatewayscript('local:///isp/policy/xslt-to-js-bridge.js', $params, false())"/>
    </func:result>
  </func:function>


    <!-- ======================================================================= -->
  <func:function name="apim:getManagedObjectName">
    <xsl:param name="type" /> <!-- Required -->
    <xsl:param name="name" />

    <xsl:variable name="params">
      <parameter name="funcName">getManagedObjectName</parameter>
      <parameter name="args">
          <xsl:text>[{"name":"</xsl:text>
          <xsl:value-of select="string($name)"/>
          <xsl:text>","asObject": "</xsl:text>
          <xsl:text>true</xsl:text>
          <xsl:text>"},"</xsl:text>
          <xsl:value-of select="string($type)"/>
          <xsl:text>"]</xsl:text>
      </parameter>
    </xsl:variable>

    <func:result>
      <xsl:copy-of select="dp:gatewayscript('local:///isp/policy/xslt-to-js-bridge.js', $params, false())"/>
    </func:result>
  </func:function>

  <func:function name="apim:determineMediaType">

    <xsl:variable name="mediaType">

     <!-- If the original input media is specified, set the output media as that value. This will ensure
     that the policy does not change the content type from text/xml to application/xml for example. If it
     is not specified (the original content type is the name of the variable or is empty, it will default to
     input-media (i.e. application/xml). -->
      <xsl:variable name="originalContentType">
         <xsl:choose>
           <xsl:when test="dp:responding() = true()">
             <xsl:variable name="temp" select="normalize-space(dp:variable('var://service/original-response-content-type'))" />
             <xsl:choose>
               <xsl:when test="not($temp = 'var://service/original-response-content-type')">
                 <xsl:value-of select="$temp" />
               </xsl:when>
               <xsl:otherwise>
                 <xsl:value-of select="/.." />
               </xsl:otherwise>
             </xsl:choose>
           </xsl:when>
           <xsl:otherwise>
             <xsl:variable name="temp" select="normalize-space(dp:variable('var://service/original-content-type'))" />
             <xsl:choose>
               <xsl:when test="not($temp = 'var://service/original-content-type')">
                 <xsl:value-of select="$temp" />
               </xsl:when>
               <xsl:otherwise>
                 <xsl:value-of select="/.." />
               </xsl:otherwise>
             </xsl:choose>
           </xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      <xsl:variable name="usePolicyOutput" select="dp:variable('var://context/_apimgmt/use-policy-output')"/>
      <xsl:variable name="policyOutputMediaType" select="dp:variable('var://context/_apimgmt/policy-output-mediaType')"/>
      <xsl:variable name="content-type-override" select="dp:variable('var://context/_apimgmt/content-type-override')"/>

      <xsl:choose>
        <xsl:when test="string-length($content-type-override) &gt; 0">
          <xsl:value-of select="$content-type-override"/>
        </xsl:when>
        <xsl:when test="string-length($usePolicyOutput) &gt; 0 and string-length($policyOutputMediaType) &gt; 0">
          <xsl:value-of select="$policyOutputMediaType"/>
        </xsl:when>
        <xsl:when test="$originalContentType">
          <xsl:value-of select="$originalContentType"/>
        </xsl:when>
      </xsl:choose>
    </xsl:variable>

    <func:result>
      <xsl:value-of select="string($mediaType)"/>
    </func:result>
  </func:function>

</xsl:stylesheet>
Lenka
  • 75
  • 11
  • Here is my XSLT, none of them are working for me. – Lenka Oct 28 '22 at 14:43
  • We might guess that `$payload` is not what you think it is, but we would have no way of confirming that because you've not included `apim.custom.xsl`. Without a true [mcve], a lot of needless back-and-forth would have to continue. – kjhughes Oct 28 '22 at 14:58
  • I am adding the `apim.custom.xsl` for your reference. And the `$payload` is exactly what I have pasted at the beginning. – Lenka Oct 28 '22 at 15:17
  • 1
    That's not a ***minimal*** [mcve]. – kjhughes Oct 28 '22 at 15:38

3 Answers3

1

Given the posted XML, and assuming you've declared the namespace prefix similarly in your XSLT (xmlns:ad="http://www.thehtf.co.uk/Data/V1.0") this XPath,

//ad:pd

will select all pd elements in the document in the http://www.thehtf.co.uk/Data/V1.0 namespace.


One of your examples,

ad:sgRes/ad:Msg/ad:cpn/ad:ist/ad:tm/ad:pd

would have worked if the current node was the root node. Change the XPath from a relative to an absolute XPath to eliminate the dependency:

/ad:sgRes/ad:Msg/ad:cpn/ad:ist/ad:tm/ad:pd

Another of your XPaths,

//*:pd

would have worked in XPath 2.0 and up.


See also

kjhughes
  • 106,133
  • 27
  • 181
  • 240
0

Have you tried this:

//*[local-name()='pd']

but preferable to use

//ad:pd

So simple.

Thanks kjhughes for your comment

Prophet
  • 32,350
  • 22
  • 54
  • 79
-1

I got this sorted by using an XSL to remove all the namespace before it reaches to my original XSL. And XPATH //pd worked.

The code I used to remove namespace was:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

<!-- Stylesheet to remove all namespaces from a document -->

<!-- template to copy elements -->
<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
</xsl:template>

<!-- template to copy attributes -->
<xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

<!-- template to copy the rest of the nodes -->
<xsl:template match="comment() | text() | processing-instruction()">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

Lenka
  • 75
  • 11
  • As already [mentioned](https://stackoverflow.com/questions/74225595/correct-xpath-for-a-namespaced-element/74262356#comment131047837_74225657), ignoring namespaces is bad practice. The assumption musr be that namespaces are there for a reason, and removing them may produce incorrect results such as mistaking an element in one namespace for an element in another. – michael.hor257k Oct 31 '22 at 11:18