0
votes

I have the following XML. Under the root node I have 'Search' node which holds configuration and 'Req' node which has Request. Inside 'Req' node there is a 'classId' node. I am storing the value I have a complex problem here. I have a 'appendString' node in my final result. First I need to check if a child node inside 'Req' node has value in it. If it has value I need to get the node name and match the node inside AllClass/class1/node3 and get its value and finally I need to form a String inside 'appendString' node like this 'Childname1=value1,Childname2=value2'. Please help.Thanks

My XML

<root>
  <ns:Search xmlns:ns="http://example.com/1.0/">
    <ns:AllClass>
      <ns:class1>
        <ns:node1>fhgfjh</ns:node1>
        <ns:node2>Aprtyrtyril</ns:node2>
        <ns:node3>
            <ns:firstChild>Childname1</ns:firstChild>
            <ns:SecondChild>Childname2</ns:SecondChild>
        </ns:node3>
      </ns:class1>
      <ns:class2>
        <ns:node1>dfgd</ns:node1>
        <ns:node2>trytyu</ns:node2>
        <ns:node3>
            <ns:firstChild>Childname11</ns:firstChild>
            <ns:SecondChild>Childname22</ns:SecondChild>
            <ns:ThirdChild>Childname33</ns:ThirdChild>
        </ns:node3>
      </ns:class2>
      .
      .
      .
      .
      .
      .
    </ns:AllClass>
  </ns:Search>
  <ns:Req xmlns:ns="http://example.com/1.0/">
    <ns:classId>class1</ns:classId>
    <ns:className>asdfg</ns:className>
    <ns:firstChild>value1</ns:firstChild>
    <ns:SecondChild>value2</ns:SecondChild>
    <ns:ThirdChild></ns:ThirdChild>
    <ns:FourthChild></ns:FourthChild>
    .
    .
    .
    .
    .
  </ns:Req>
</root>

XSL

<xsl:template match="root/Req">
    <xsl:variable xmlns:ns="http://example.com/1.0/" name="class_tmp" select="/root/ns:Req/ns:classId" />
    <xsl:variable name="class" select="concat(&apos;ns:&apos;,$class_tmp)" />
    <ns1:Response xmlns:ns1="http://example.com/ns/">
      <ns1:SearchString>
        <xsl:value-of xmlns:ns="http://example.com/1.0/" xmlns:ns1="http://example.com/1.0/" select="/root/ns:Search/ns:AllClassM/*[name()=$class]/ns:node2" />
      </ns1:SearchString>
      <xsl:apply-templates/>
    </ns1:Response>
  </xsl:template>
  <xsl:template match="root/Req/*">
    <ns1:appendString></ns1:appendString>
  </xsl:template>

Final XML

<ns1:Response xmlns:ns1="http://example.com/ns/">
<ns1:SearchString>Aprtyrtyril</ns1:SearchString>
<ns1:appendString>Childname1=value1,Childname2=value2</ns1:appendString>
</ns1:Response>  
2
attach your sample expected result XML - nawazlj
@nawazlj Added sample XML - SM Ahmed

2 Answers

0
votes

--- edited in response to clarifications ---

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://example.com/1.0/"
xmlns:ns1="http://example.com/ns/"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="id" match="ns:AllClass/*" use="name()" />
<xsl:key name="label" match="ns:node3/*" use="concat(name(), '|', name(../..))" />

<xsl:template match="/root">
    <xsl:variable name="classId" select="concat('ns:', ns:Req/ns:classId)" />
    <ns1:Response>
        <ns1:SearchString>
            <xsl:value-of select="key('id', $classId)/ns:node2" />
        </ns1:SearchString>
        <ns1:appendString>
            <xsl:for-each select="ns:Req/*[not(self::ns:classId or self::ns:className)][text()]">
                <xsl:value-of select="key('label', concat(name(), '|', $classId))" />
                <xsl:text>=</xsl:text>
                <xsl:value-of select="." />
                <xsl:if test="position()!=last()">
                    <xsl:text>,</xsl:text>
                </xsl:if>
            </xsl:for-each>
        </ns1:appendString>
    </ns1:Response>  
</xsl:template>

</xsl:stylesheet>

This assumes any node under ns:Req except ns:classId and ns:className is a "child node" that needs to be listed if not empty.

0
votes

Going in the opposite direction as suggested earlier by Michael, below is the working XSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://example.com/1.0/"
xmlns:ns1="http://example.com/ns/"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="id" match="ns:AllClass/*" use="name()" />
<xsl:key name="req" match="ns:Req/*" use="name()" />

<xsl:template match="root">
<xsl:variable name="classId" select="concat('ns:', ns:Req/ns:classId)" />
    <ns1:Response>
        <ns1:SearchString>
            <xsl:value-of select="key('id', $classId)/ns:node2" />
        </ns1:SearchString>
        <ns1:appendString>
            <xsl:for-each select="key('id', $classId)/ns:node3/*">
                <xsl:value-of select="." />
                <xsl:text>=</xsl:text>
                <xsl:value-of select="key('req',name())" />
                <xsl:if test="position()!=last()">
                    <xsl:text>,</xsl:text>
                </xsl:if>
            </xsl:for-each>
        </ns1:appendString>
    </ns1:Response>  
</xsl:template>

</xsl:stylesheet>