VSS
VSS

Reputation: 306

How to run xpath on specific xml using xslt

The question is almost same as one of my question here edit specific xml using xpath

But now the problem is different. The xml structure is little different now. The solution on earlier question will not work here.

I have below xml file

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
    <map key="Request">
        <map key="Headers">
            <string key="Accept">application/json</string>
            <string key="Content-Type">application/json</string>
        </map>
        <map key="Payload">
            <map key="root">
                <array key="req1">
                    <string>puneet</string>
                    <string>taneja</string>
                </array>
                <array key="req2">
                    <string>ratan</string>
                </array>
            </map>
        </map>
    </map>
</map>

Below are the XPATHS

/Request/Headers/Accept=app
/Request/Headers/Content-Type=json
/Request/Payload/root/req1[2]=singh
/Request/Payload/root/req1[1]=pradeep
/Request/Payload/root/req2=suman

I want updated result xml as below

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
    <map key="Request">
        <map key="Headers">
            <string key="Accept">application/json</string>
            <string key="Content-Type">application/json</string>
        </map>
        <map key="Payload">
            <map key="root">
                <array key="req1">
                    <string>pradeep</string>
                    <string>singh</string>
                </array>
                <array key="req2">
                    <string>suman</string>
                </array>
            </map>
        </map>
    </map>
</map>

Basically I want to change my xml on given xpaths using xslt. Check out the code at this location xsltfiddle.liberty-development.net

It will be helpful for me to have update in same earlier solution for this scenario as well.

Upvotes: 1

Views: 97

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167401

To get paths like

/Request/Payload/root/req1[2]=singh
/Request/Payload/root/req1[1]=pradeep

working you can add a template

<xsl:template match=".[contains(., '[') and contains(., '=')]" mode="step">
    <xsl:if test="position() gt 1">/</xsl:if>
    <xsl:sequence select="'*[@key = ''' || substring-before(., '[') || ''']/*[' || replace(., '^[^\[]+\[([0-9]+)\].*$', '$1') || ']'"/>
</xsl:template>

so that code like

   <xsl:template match="*[@key = 'Request']/*[@key = 'Payload']/*[@key = 'root']/*[@key = 'req1']/*[1]">
      <xsl:copy>
         <xsl:copy-of select="@*"/>pradeep</xsl:copy>
   </xsl:template>
   <xsl:template match="*[@key = 'Request']/*[@key = 'Payload']/*[@key = 'root']/*[@key = 'req1']/*[2]">
      <xsl:copy>
         <xsl:copy-of select="@*"/>singh</xsl:copy>
   </xsl:template>

is being generated, see https://xsltfiddle.liberty-development.net/bdxtpY/1.

I am currently not sure how to infer from /Request/Payload/root/req2=suman that there is an array member involved.

Upvotes: 3

Related Questions