xml - split nodes and assign them to variables for matching -
this question similar merge 2 elements using xslt based on attribute values trying put in different way understand better.
i have xml file 2 elements names same, second element part of first element. example:
<?xml version="1.0" encoding="utf-8" standalone="no"?> <!-- first element--> <book> <mbean code="org.book.mybooks" name="mycompany.props.jndi:name=mybookprops"> <attribute name="bookprops"> abc.mybook.onebook=@value@ def.mybook.twobook=@value@ ghi.myebook.threebook=@value@ </attribute> </mbean> <!--this second element , part of first element--> <book> <mbean code="org.book.mybooks" name="mycompany.props.jndi:name=mybookprops"> <attribute name="bookprops"> abc.mybook.onebook=@new_value@ def.mybook.twobook=@new_value@ ghi.myebook.fourbook=@value@ </attribute> </mbean> </book><!--closing tag of second element--> </book><!--closing tag of first element-->
objective is:
combine both elements 1 element , if both elements having similar nodes value of nodes different replace values of first attribute nodes second attribute nodes.
procedure thinking of:
- sort nodes of first , second elements.
- split nodes of first element , assign variables. example: node of first element abc.mybook.onebook=@value@ split 2 , assigned them variables varaible1=abc.mybook.onebook , varaible2=@value@.
- simillar way split nodes of second element , assign them variables. example node of second element abc.mybook.onebook=@new_value@ split 2 , assigned them variables varaible3=abc.mybook.onebook , varaible4=@new_value@.
- now match first element variables second element variables. example: if variable1 equals variable3 replace variable2 varaible4; else copy first element node , copy second element node.
this can done in shell or bash since requirement xslt, trying figure out how can accomplished.
the final output expecting is:
<book> <mbean code="org.book.mybooks" name="mycompany.props.jndi:name=mybookprops"> <attribute name="bookprops"> abc.mybook.onebook=@new_value@ def.mybook.twobook=@new_value@ ghi.myebook.threebook=@value@ ghi.myebook.fourbook=@value@ </attribute> </mbean> </book>
i use analyze-string
extract parts , can group:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:mf="http://example.com/mf" exclude-result-prefixes="xs mf"> <xsl:function name="mf:props" as="element(value)*"> <xsl:param name="input" as="xs:string"/> <xsl:analyze-string select="$input" regex="(\s+)=(\s+)"> <xsl:matching-substring> <value key="{regex-group(1)}"><xsl:value-of select="regex-group(2)"/></value> </xsl:matching-substring> </xsl:analyze-string> </xsl:function> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* , node()"/> </xsl:copy> </xsl:template> <xsl:template match="book[book]/mbean/attribute"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:variable name="props"> <xsl:sequence select="mf:props(.), mf:props(../following-sibling::book/mbean/attribute)"/> </xsl:variable> <xsl:text> </xsl:text> <xsl:for-each-group select="$props/value" group-by="@key"> <xsl:apply-templates select="current-group()[last()]" mode="value-to-prop"/> </xsl:for-each-group> </xsl:copy> </xsl:template> <xsl:template match="value" mode="value-to-prop"> <xsl:value-of select="concat(' ', @key, '=', ., ' ')"/> </xsl:template> <xsl:template match="book/book"/> </xsl:stylesheet>
saxon 9.5 transforms given input into
<?xml version="1.0" encoding="utf-8"?><!-- first element--><book> <mbean code="org.book.mybooks" name="mycompany.props.jndi:name=mybookprops"> <attribute name="bookprops"> abc.mybook.onebook=@new_value@ def.mybook.twobook=@new_value@ ghi.myebook.threebook=@value@ ghi.myebook.fourbook=@value@ </attribute> </mbean> <!--this second element , part of first element--> <!--closing tag of second element--> </book><!--closing tag of first element-->
Comments
Post a Comment