Ankur Raiyani
Ankur Raiyani

Reputation: 1708

XSLT How to filter the data using array

I am beginner in XSLT. My Source XML:

<Request>
   <Documents>
      <Doc Type="A">123</Doc>
      <Doc Type="C">345</Doc>
   </Documents>
</Request>

My response XML:

<Response>
   <RequestedDoc>
       <Doc Type="A">123</Doc>
       <Doc Type="C">345</Doc>
   </RequestedDoc>
   <Result>
      <Document>
         <Id>A123</Id>
         <Name>Doc1</Name>
      </Document>
      <Document>
         <Id>E143</Id>
         <Name>Doc2</Name>
      </Document>
      <Document>
         <Id>C345</Id>
         <Name>Doc3</Name>
      </Document>
      <Document>
         <Id>D153</Id>
         <Name>Doc4</Name>
      </Document>
   </Result>
</Response>

i need to filter the Result tag using the RequestedDoc tag. i have tried below XSLT but it returns only the 1st result.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" indent="yes" />
   <xsl:variable name="requestedDoc" select="//RequestedDoc/Doc"/>

   <xsl:template match="Response">
      <xsl:element name="FilterResult">
          <xsl:apply-templates select="//Result/Document[contains(Id,$requestedDoc)]"/>
      </xsl:element>
   </xsl:template>

   <xsl:template match="Document">
      <xsl:element name="Name">
         <xsl:value-of select="Name"/>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

but this XSLT always return data for first Doc A123.

<FilterResult>
  <Name>Doc1</Name>
</FilterResult>

Expected result is

<FilterResult>
  <Name>Doc1</Name>
  <Name>Doc3</Name>
</FilterResult>

Please help.

Upvotes: 1

Views: 1139

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243549

This transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <FilterResult>
      <xsl:apply-templates/>
     </FilterResult>
 </xsl:template>

 <xsl:template match="Document[substring(Id,2) = /*/RequestedDoc/*]">
  <xsl:copy-of select="Name"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

when applied on the provided Response document:

<Response>
   <RequestedDoc>
       <Doc Type="A">123</Doc>
       <Doc Type="C">345</Doc>
   </RequestedDoc>
   <Result>
      <Document>
         <Id>A123</Id>
         <Name>Doc1</Name>
      </Document>
      <Document>
         <Id>E143</Id>
         <Name>Doc2</Name>
      </Document>
      <Document>
         <Id>C345</Id>
         <Name>Doc3</Name>
      </Document>
      <Document>
         <Id>D153</Id>
         <Name>Doc4</Name>
      </Document>
   </Result>
</Response>

produces the wanted, correct result:

<FilterResult>
   <Name>Doc1</Name>
   <Name>Doc3</Name>
</FilterResult>

Upvotes: 1

Related Questions