xml - Update the element name based on xpath from external file -
please suggest how update elements' name based on external file based on xpath given in it.
i have tried, few variables store xpath external file, template matched element's xpath, unable required info. please suggest.
external file (findreplaceelements.ini):
<root> <tofind>aside/p</tofind> <toreplace><p class="aside_para"></p></toreplace> <tofind>aside[@class="sidenote1"]/p</tofind> <toreplace><p class="aside_para1"></p></toreplace> <tofind>body/p</tofind> <toreplace><p class="body_para"></p></toreplace> <tofind>body/div/div/h1</tofind> <toreplace><p class="body_h_2"></p></toreplace> <tofind>body/div/div/div/h1</tofind> <toreplace><p class="body_h_3"></p></toreplace> </root>
input xml:
<article> <body> <p>the body para1</p> <aside><p>aside para1</p></aside> <aside class="sidenote1"><p>aside para2</p></aside> <div><div class="special"><h1>the heading1</h1></div></div> <div><div><div><h1>the heading2</h1></div></div></div> </body> </article>
required result:
<article> <body> <p class="body_para">the body para1</p> <aside><p class="aside_para">aside para1</p></aside> <aside class="sidenote1"><p class="aside_para1">aside para2</p></aside> <div><div class="special"><p class="body_h_2">the heading1</p></div></div> <div><div><div><p class="body_h_3">the heading2</p></div></div></div> </body> </article>
xslt:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:template match="node()|@*"> <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> </xsl:template> <xsl:variable name="vardocelemsini" select="document('findreplaceelements.ini')"/> <xsl:variable name="vardqote">"</xsl:variable> <xsl:template match="p"> <xsl:variable name="nodeasstr"><xsl:value-of select="name(.)"/></xsl:variable><!--string name of element --> <xsl:variable name="varallmatchedeles"> <!--getting elements name ini file--> <xsl:for-each select="$vardocelemsini/root/tofind"> <xsl:variable name="varnextelemini"><xsl:value-of select="following-sibling::*[1]/name()"/></xsl:variable><!--from ini file, required element name--> <xsl:variable name="varpathini"><!--xpath of element ini file--> <xsl:for-each select="$vardocelemsini/root/tofind/tokenize(text(), '/')[not(position()=last())]"> <xsl:value-of select="."/><xsl:value-of select="'/'"/> </xsl:for-each> </xsl:variable> <xsl:variable name="varnameelem1"> <xsl:for-each select="tokenize(text(), '/')[last()]"> <xsl:if test=". = $nodeasstr"> <xsl:value-of select="$varnextelemini"/> </xsl:if> </xsl:for-each> </xsl:variable> </xsl:for-each> </xsl:variable> <xsl:variable name="varpath"><!--xpath of element given input file --> <xsl:value-of select="concat(ancestor::*[2]/name(), '/', parent::*/name())"/> </xsl:variable> <xsl:choose> <xsl:when test="$varallmatchedeles=$varpath"> <xsl:element name="{$varnextelemini}"><xsl:apply-templates select="@*|node()"/></xsl:element> </xsl:when> <xsl:otherwise> <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
one more xslt tried below: unable result
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:template match="node()|@*"> <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> </xsl:template> <xsl:variable name="vardocelemsini" select="document('findreplaceelements.ini')"/> <xsl:variable name="vardqote">"</xsl:variable> <xsl:template match="h1"> <xsl:call-template name="tempinsertelemsattribs"/> </xsl:template> <xsl:template match="h2"> <xsl:call-template name="tempinsertelemsattribs"/> </xsl:template> <xsl:template name="tempinsertelemsattribs"> <xsl:variable name="varreqelemname"> <xsl:for-each select="$vardocelemsini/root/tofind/*[name()=current()/name()]"> <xsl:value-of select="parent::tofind/following-sibling::*[1][name()='toreplace']/child::*/name()"/> </xsl:for-each> </xsl:variable> <xsl:variable name="varreqelemnameattrib"> <xsl:for-each select="$vardocelemsini/root/tofind/*[name()=current()/name()]/parent::tofind/following-sibling::*[1][name()='toreplace']/child::*/@*"> <xsl:value-of select="concat(name(), '=', $vardqote, ., $vardqote)"/><xsl:if test="not(position()=last())"><xsl:text> </xsl:text></xsl:if> </xsl:for-each> </xsl:variable> <xsl:choose> <xsl:when test="string-length($varreqelemname) gt 0"> <xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="$varreqelemname"/> <xsl:if test="string-length($varreqelemnameattrib) gt 0"><xsl:value-of select="concat(' ', $varreqelemnameattrib)"/></xsl:if> <xsl:text disable-output-escaping="yes">></xsl:text> <xsl:apply-templates/> <xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="$varreqelemname"/><xsl:text disable-output-escaping="yes">></xsl:text> </xsl:when> <xsl:otherwise> <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
i suggest in 2 steps:
first, apply following stylesheet "external file":
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:axsl="http://www.w3.org/1999/xsl/transformalias"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/> <xsl:template match="/root"> <axsl:stylesheet version="2.0"> <axsl:template match="@*|node()"> <axsl:copy> <axsl:apply-templates select="@*|node()"/> </axsl:copy> </axsl:template> <xsl:apply-templates select="tofind"/> </axsl:stylesheet> </xsl:template> <xsl:template match="tofind"> <axsl:template match="{.}"> <xsl:apply-templates select="following-sibling::toreplace[1]/*"/> </axsl:template> </xsl:template> <xsl:template match="toreplace/*"> <xsl:copy> <xsl:copy-of select="@*"/> <axsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
the result in example be:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="2.0"> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="aside/p"> <p class="aside_para"> <xsl:apply-templates select="@*|node()"/> </p> </xsl:template> <xsl:template match="aside[@class="sidenote1"]/p"> <p class="aside_para1"> <xsl:apply-templates select="@*|node()"/> </p> </xsl:template> <xsl:template match="body/p"> <p class="body_para"> <xsl:apply-templates select="@*|node()"/> </p> </xsl:template> <xsl:template match="body/div/div/h1"> <p class="body_h_2"> <xsl:apply-templates select="@*|node()"/> </p> </xsl:template> <xsl:template match="body/div/div/div/h1"> <p class="body_h_3"> <xsl:apply-templates select="@*|node()"/> </p> </xsl:template> </xsl:stylesheet>
this result xslt stylesheet of own. applying input example produce following result:
<?xml version="1.0" encoding="utf-8"?><article> <body> <p class="body_para">the body para1</p> <aside><p class="aside_para">aside para1</p></aside> <aside class="sidenote1"><p class="aside_para1">aside para2</p></aside> <div><div class="special"><p class="body_h_2">the heading1</p></div></div> <div><div><div><p class="body_h_3">the heading2</p></div></div></div> </body> </article>
note of these rules ambiguous. there dangers undertake when farm out process of producing xslt external agents.
Comments
Post a Comment