select node based on other node in certain order
<command>abc</command>
<Pset name="X_number">
<var name="Y_name">A</var>
<var name="Y_num">6</var>
<var name="Z_name">C</var>
</Pset>
<Pset name="T_num">
<var name="T_num">1</var>
</Pset>
<Pset name="T_num">
<var name="T_num">2</var>
</Pset>
<Pset name="T_status">
<var name="T_status">U</var>
</Pset>
<Pset name="T_status">
<var name="T_status">V</var>
</Pset>
<Pset name="end_matching">
</Pset>
<Pset name="X_number">
We have to get following structure out of it :
<Event>
<module_num>A</module_num> <here module_num corrosponds to <var name="Y_name">A</var> and display value of Y_name)
<Tnumber>1</Tnumber> (here TNumber(you can give any name, I kept Tnumber to keep it simple) corresponds to first Pset of T_Num and get the value from <var name="T_num">1</var>)
<Tstatus>U</Tstatus> (here Tstatus corresponds to first Pset of T_status and get the value from <var name="T_Status">U</var>)
</Event>
<Event>
<module_num>A</module_num> <here module_num is same as first Event set>
Tnum>2</Tnum> ( Here also it is secon开发者_高级运维d one , and there can be multiple )
<Tstatus>V</Tstatus>
</Event>
Module_num will reamin common to all event which originates from X_number and Tstatus and Tnum will be related based on their position, we have to iterate through all the T_num/ T_status before start of another X_number .
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kPsetByPrecX_number"
match="Pset[@name[.='T_num' or .='T_status']]"
use="generate-id(preceding-sibling::Pset[@name='X_number'][1])"/>
<xsl:template match="t">
<xsl:copy>
<xsl:apply-templates select="Pset[@name='X_number']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Pset[@name='X_number']">
<xsl:variable name="vCurrent-group"
select="key('kPsetByPrecX_number',generate-id())"/>
<xsl:apply-templates select="$vCurrent-group[@name='T_num']">
<xsl:with-param name="pModule" select="var[@name='Y_name']"/>
<xsl:with-param name="pStatus"
select="$vCurrent-group[@name='T_status']"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Pset[@name='T_num']">
<xsl:param name="pModule"/>
<xsl:param name="pStatus" select="/.."/>
<xsl:variable name="vPosition" select="position()"/>
<Event>
<module_num>
<xsl:value-of select="$pModule"/>
</module_num>
<xsl:apply-templates select="(.|$pStatus[$vPosition])/var"/>
</Event>
</xsl:template>
<xsl:template match="var">
<xsl:element name="{translate(@name,'_','')}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
With this input:
<t>
<command>abc</command>
<Pset name="X_number">
<var name="Y_name">A</var>
<var name="Y_num">6</var>
<var name="Z_name">C</var>
</Pset>
<Pset name="T_num">
<var name="T_num">1</var>
</Pset>
<Pset name="T_num">
<var name="T_num">2</var>
</Pset>
<Pset name="T_status">
<var name="T_status">U</var>
</Pset>
<Pset name="T_status">
<var name="T_status">V</var>
</Pset>
<Pset name="end_matching"></Pset>
<Pset name="X_number"/>
</t>
Output:
<t>
<Event>
<module_num>A</module_num>
<Tnum>1</Tnum>
<Tstatus>U</Tstatus>
</Event>
<Event>
<module_num>A</module_num>
<Tnum>2</Tnum>
<Tstatus>V</Tstatus>
</Event>
</t>
精彩评论