1

I have been searching StackOverflow for a while yet unsuccessful. My aim is to filter Employee XML documents. The Input XML has around 9000 Employees, and I have multiple target systems who wants a subset of these Employee Records based on different selection criteria for each target system. Sample Input:

<Employees>
  <Employee>
    <id>1</id>
    <name>Name1</name>
  </Employee>
  <Employee>
    <id>2</id>
    <name>Name2</name>
  </Employee>
  <Employee>
    <id>3</id>
    <name>Name3</name>
  </Employee>
  <Employee>
    <id>4</id>
    <name>Name4</name>
  </Employee>
</Employees>

The output should be of the same structure but reduced nodes based on the selection criteria(XPATH). How can I pass the dynamic XPath to an XSLT stylesheet and get the filtered employees as output? Please note the complete Xpath Expression along with the filtering conditions are passed as one string.

Desired output:

<Employees>
      <Employee>
        <id>2</id>
        <name>Name2</name>
      </Employee>
      <Employee>
        <id>3</id>
        <name>Name3</name>
      </Employee>
 </Employees>
3
  • Maintaing the root node is optional. The root node can be ignored and the output can be just with multiple Employee Nodes matching the selection criteria as well. Commented Dec 14, 2021 at 11:56
  • In XSLT 3 using a static parameter and a shadow attribute this is straightforward, with the exception that you need to use an XSLT 3 processor and its API or interface to use that feature. Commented Dec 14, 2021 at 12:18
  • You might consider just using XPath in your program to do the filtering, in C# for example using XmlDocument.SelectNodes( "//your/dynamic/xapth[@filter=1]" ). Then format the results in XSL. Commented Dec 14, 2021 at 13:50

1 Answer 1

2

With XSLT 3.0, xsl:evaluate for dynamic XPath evaluation. You could accept the XPath as an xsl:param (shown with an example default XPath value) and then evaluate it.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:output indent="yes"/>
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:param name="path" select="'/Employees/Employee[number(id)[. gt 1 and . lt 4]]'" />
        
    <xsl:template match="Employees">
        <xsl:copy>
            <xsl:evaluate xpath="$path" context-item="."/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

4 Comments

This code only returns the values inside the nodes, and not as XML output.
well, you haven't provided an example of the desired output, so it's difficult to guess what you want. You can make it well-formed XML output by wrapping the apply-templates in some element, you can copy the document element, etc.
Updated the desired output. Does the evaluate function return just the values, or it returns along with the node information?
xsl:evaluate will return the nodes, which you can simply return in the template, instead of applying templates if you aren't going to transform or filter anything. I have updated the solution.

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.