I want to generate xpath for xml element which is inside the CDATA.
INPUT :
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<CSBIV xmlns="http://tempuri.org/">
<Response>true</Response>
<CSBIV_CargoResult><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<ShipmentRecords>
<CustomerInfo>
<SoftwareVersion>6.0</SoftwareVersion>
<DefaultAccountNo>530901961</DefaultAccountNo>
</CustomerInfo>
</ShipmentRecords>
]]></CSBIV_CargoResult>
</CSBIV>
</s:Body>
</s:Envelope>
XSLT Used to generate xpath:
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:param name="path"/>
<xsl:variable name="my-path">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="concat('/',name())"/>
<xsl:if test="(preceding-sibling::*|following-sibling::*)[name()=name(current())]">
<xsl:value-of select="concat('[',count(preceding-sibling::*[name()=name(current())])+1,']')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:variable name="elementXpath" select="replace($my-path, '/[a-zA-Z0-9-]*?:|/[a-zA-Z0-9-]*?','/*:')"/>
<xsl:attribute name="xpath">
<xsl:value-of select="concat($elementXpath,'/text()')"/>
</xsl:attribute>
<xsl:copy-of select="@*"/>
<xsl:for-each select="@*">
<xsl:attribute name="{name()}" select="concat($elementXpath,'/@',name())" separator=""/>
</xsl:for-each>
<xsl:apply-templates>
<xsl:with-param name="path" select="$my-path"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
So this will give me this output.
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xpath="/*:Envelope/text()">
<s:Body xpath="/*:Envelope/*:Body/text()">
<CSBIV xmlns="http://tempuri.org/" xpath="/*:Envelope/*:Body/*:CSBIV/text()">
<Response xpath="/*:Envelope/*:Body/*:CSBIV/*:Response/text()"/>
<CSBIV_CargoResult xpath="/*:Envelope/*:Body/*:CSBIV/*:CSBIV_CargoResult/text()"/>
</CSBIV>
</s:Body>
</s:Envelope>
So this ignore CDATA section. So I want something like this below as output. I want that it will give xpath for inside xml in CDATA with concating parent xpath with |@|CDATA|@|
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xpath="/*:Envelope/text()">
<s:Body xpath="/*:Envelope/*:Body/text()">
<CSBIV xmlns="http://tempuri.org/" xpath="/*:Envelope/*:Body/*:CSBIV/text()">
<Response xpath="/*:Envelope/*:Body/*:CSBIV/*:Response/text()"/>
<CSBIV_CargoResult xpath="/*:Envelope/*:Body/*:CSBIV/*:CSBIV_CargoResult/text()">
<ShipmentRecords xpath="/*:Envelope/*:Body/*:CSBIV/*:CSBIV_CargoResult|@|CDATA|@|/*:ShipmentRecords/text()">
<CustomerInfo xpath="/*:Envelope/*:Body/*:CSBIV/*:CSBIV_CargoResult|@|CDATA|@|/*:ShipmentRecords/*:CustomerInfo/text()">
<SoftwareVersion xpath="/*:Envelope/*:Body/*:CSBIV/*:CSBIV_CargoResult|@|CDATA|@|/*:ShipmentRecords/*:CustomerInfo/*:SoftwareVersion/text()"/>
<DefaultAccountNo xpath="/*:Envelope/*:Body/*:CSBIV/*:CSBIV_CargoResult|@|CDATA|@|/*:ShipmentRecords/*:CustomerInfo/*:DefaultAccountNo/text()"/>
</CustomerInfo>
</ShipmentRecords>
</CSBIV_CargoResult>
</CSBIV>
</s:Body>
</s:Envelope>
You can do e.g.
Note that your CDATA, due to white space before the XML declaration, doesn't parse as XML, so for that example to work you need e.g.
instead.
I have used the result of the
pathfunction to construct the xpath attribute value but you should be able to replace that with a custom function producing your wanted format.