Reputation: 11
i have just created a XSL transformation where i am transform Xml to xHTML and back. It is my first time working with XSLT. Now i am building the "back part" a reverse transformation and there i am stuck.
Introduction/Overview
So the base XML contains two nodes (frags) where i am looking for:
<frag id="10" name="Editable_Fragment" >
<child id="11"></child>
</frag>
<frag id="20" name="Editable_Fragment2">
<child id="21"></child>
</frag>
Btw there are a lot of fragments inside this XML but i just looking for "editable" ones! So i have create a XSLT like this:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="/review-case/review-document/review-channel/content/region/section/frag[@name='Editable_Fragment']/node()"/>
<xsl:apply-templates select="/review-case/review-document/review-channel/content/region/section/frag[@name='Editable_Fragment2']/node()"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
The content of both nodes are hold together in a rich text editor as a string! The content looks like this:
<child id="11" name="Editable_Fragment">....data...</child>
<child id="21" name="Editable_Fragment">....data...</child>
In the rich text editor i am changing some data of both nodes and afterwards i want to update the data with a so called reverse transformation.
Reverse Transformation Issue
The string with both "child" tags will be used for further processing within a parameter mpTransformParameters. I have to use this parameter. I know with the following XSLT code i am just updating frag id="10" with child id="11" and child id="21".
My Question is, how can i merge back updated child id="11" to "frag id=10" and child id="21 to "frag id=20" if both are together in on string?
"Reverse" XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:param name="mpTransformParameters"/>
<xsl:template match="review-case/review-document/review-channel/content/region/section/frag/child[@name='Editable_Fragment']">
<xsl:value-of select="$mpTransformParameters" disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Thanks a lot
Upvotes: 1
Views: 441
Reputation: 31011
Try such XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="mpTransformParameters">
<child id="11" name="Editable_Fragment">..data 11..</child>
<child id="21" name="Editable_Fragment">..data 22..</child>
</xsl:param>
<xsl:template match="section">
<xsl:variable name="tbl"
select="tokenize($mpTransformParameters, '</child>')"/>
<xsl:copy>
<xsl:for-each select="$tbl">
<xsl:analyze-string select="."
regex="id="(\d+)".*>(.*)">
<xsl:matching-substring>
<xsl:variable name="id" select="number(regex-group(1)) - 1"/>
<xsl:variable name="txt" select="regex-group(2)"/>
<xsl:variable name="nm">
<xsl:if test="$id=10"><xsl:text>Editable_Fragment</xsl:text></xsl:if>
<xsl:if test="$id=20"><xsl:text>Editable_Fragment2</xsl:text></xsl:if>
</xsl:variable>
<xsl:element name="frag">
<xsl:attribute name="id" select="$id"/>
<xsl:attribute name="name" select="$nm"/>
<xsl:value-of select="$txt"/>
</xsl:element>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
I deliberately choose XSLT 2.0, because it would be too tedious to write it in version 1.0.
For the purpose of the test run, I assigned a sample value to mpTransformParameter.
I prepared slightly simplified XML input with dummy content of section element, as you wrote, that the actual content is in mpTransformParameters:
<region>
<section>Dummy content
</section>
</region>
Using it, I got the following result:
<region>
<section>
<frag id="10" name="Editable_Fragment">..data 11..</frag>
<frag id="20" name="Editable_Fragment2">..data 22..</frag>
</section>
</region>
Upvotes: 1