Issue with calling a function to fetch the text from xml document using xsl

83 Views Asked by At

I want to call the variable(referencedObjects) or call the function to print the text inside value element.

I am getting the result without the function but If I add a xsl function and a variable inside, I am not able to fetch the variable hence not getting the required result.

Current error is function undefined

Need a solution to call the function to fetch the text inside value element.

Basically, I need to transform the input to the expected result.

Any help would be appreciated

Input

<Metadata id="WTPart_1398662" source="wt.part.WTPart|com.ptc.PHBase|com.ptc.PHModel">
         <Property token="number">
            <Value>PH_U-HD2</Value>
         </Property>
         <Property token="number">
            <Value>PH_U-HD3</Value>
         </Property>
 </Metadata>

Expected

<p>PH_U-HD2</p>
<p>PH_U-HD3</p>

XSL code

<xsl:stylesheet  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:my="http://itcinfotec.com/my-namespace"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    

    <xsl:function name="my:getRealUDProducts" as="xs:string">
           <xsl:param name="path"/>
       <xsl:variable name="referencedObjects">       
        <xsl:for-each select="//Object/Metadata[@source='wt.part.WTPart|com.ptc.PHBase|com.ptc.PHModel']">
         <xsl:value-of select="Property[@token='number']/Value" />            
        </xsl:for-each>     
    </xsl:variable> 
    </xsl:function>

     <xsl:template match="/">
        <p>
            <xsl:value-of select="my:getRealUDProducts(.)"></xsl:value-of>
        </p> 
    </xsl:template>    
    
</xsl:stylesheet>
2

There are 2 best solutions below

0
Martin Honnen On

Your function body has nothing but a variable that is not even used. And you don't use the node you pass in at all, inside of the function there is no context item defined (https://www.w3.org/TR/xslt-30/#function-result: "Within the sequence constructor, the focus is initially absent; this means that any attempt to reference the context item, context position, or context size is a dynamic error.").

I would expect the processor to give that error as soon as you try to use that variable as it tries to access a context item in e.g. //Object.

8
Michael Kay On

Your code clearly isn't going to work for all the reasons described by @MartinHonnen. But can we help you to write code that is going to work? For this we have to try and understand what you are trying to achieve.

Getting from your input to your desired output is trivially easy:

<xsl:template match="Property/Value">
  <p><xsl:value-of select="."/></p>
</xsl:template>

So why are you making it so complicated?

You say several times that having a function is a requirement. Well, it's a strange sort of requirement. What is the purpose of the required function? What part of the processing is the function needed for? It's very easy to take any part of a working stylesheet and wrap in a function, but without understanding why you want this, we can't do it for you.

Let me make some guesses. Looking at your non-working code and trying to read your mind, perhaps the input actually consists of multiple Metadata elements inside an Object element and you are trying to select one of them based on the value of its @source attribute. In that case the function you want might look like this:

<xsl:variable name="input" select="/"/>
<xsl:function name="my:getRealUDProducts" as="xs:string">
   <xsl:param name="source"/>
   <xsl:sequence select="$input/Object/Metadata[@source=$source]
                         /Property[@token='number']/Value" />            
</xsl:function>

But I may have guessed completely wrong.