Subject: RE: [xsl] Create a bit mask ? From: Saba <saba_emailme-xslt@xxxxxxxxx> Date: Wed, 10 Nov 2004 10:57:52 -0800 (PST) |
Thanks Jarno! While waiting for a response I had managed to fumble through the get it to work - I however liked the compactness of your solution and am updating my solution to reduce all the extra variables I was creating. Thanks a lot for helping me out. - Saba --- Jarno.Elovirta@xxxxxxxxx wrote: > Hi, > > > I need to convert a number of elements into a > single > > element with a bit mask as its value. Here is a > some > > sample source XML snippet: > > > > <Rule Name="Rule1"> > > <Tag Name="Tag1"/> > > <Tag Name="Tag2"/> > > </Rule> > > <Rule Name="Rule2"> > > <Tag Name="Tag1"/> > > <Tag Name="Tag3"/> > > </Rule> > > > > <Tags> > > <Tag Name="Tag1"> > > <Id>0</Id> > > </Tag> > > <Tag Name="Tag2"> > > <Id>1</Id> > > </Tag> > > <Tag Name="Tag3"> > > <Id>2</Id> > > </Tag> > > </Tags> > > > > > > I need to convert this into: > > > > <Rule Name="Rule1"> > > <TagMap>-4</TagMap> > > </Rule> > > <Rule Name="Rule2"> > > <TagMap>-6</TagMap> > > </Rule> > > > > The value in TagMap is a 32 bit bit-mask which > > contains a 0 if the Tag applies to the rule and a > 1 if > > it does not. The bit position for a tag is > determined > > by the Tag's ID value (Starting from the right > most > > bit) > > > > So the map for Rule1 is -4 which is > > 11111111111111111111111111111100 in binary. The > two > > zeros correspond to Tag1 (Id 0) and Tag2 (Id 1). > > Map value for Rule2 is -6 which is > > 11111111111111111111111111111010 corresponding to > Tag1 > > (Id 0) and Tag3 (Id 2). > > > > Can anyone help with this? I feel handicapped > without > > a processing loop construct and being able to > redefine > > the value of a variable! I am limited to using > XSLT > > 1.0 > > How does 11111111111111111111111111111100 represent > -4 in binary? If I reverse the ones and zeros (what > ever you call that operation in English), add one, > and multiply with -1 I get the results you state. > Anyhow, the stylesheet below gives you what you > wanted, but as I didn't really get the mask to value > conversion, you may have to rewrite it. The Bin2Dec > template's from Xselerator's Standard Snippet > Library, don't know who wrote it. > > <xsl:template match="Rule"> > <xsl:copy> > <xsl:apply-templates select="@*"/> > <TagMap> > <xsl:variable name="n"> > <xsl:call-template name="Bin2Dec"> > <xsl:with-param name="value"> > <xsl:apply-templates select="Tag[1]"/> > </xsl:with-param> > </xsl:call-template> > </xsl:variable> > <xsl:value-of select="-($n + 1)"/> > </TagMap> > </xsl:copy> > </xsl:template> > <xsl:template match="Tag"> > <xsl:param name="mask" > select="'00000000000000000000000000000000'"/> > <xsl:variable name="id" select="32 - > ../../Tags/Tag[@Name = current()/@Name]/Id"/> > <xsl:choose> > <xsl:when test="following-sibling::Tag"> > <xsl:apply-templates > select="following-sibling::Tag[1]"> > <xsl:with-param name="mask" > select="concat(substring($mask, 0, $id), 1, > substring($mask, $id + 1, 32))"/> > </xsl:apply-templates> > </xsl:when> > <xsl:otherwise> > <xsl:value-of > select="concat(substring($mask, 0, $id), 1, > substring($mask, $id + 1, 32))"/> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > <xsl:template match="Tags"/> > <xsl:template match="@* | node()"> > <xsl:copy> > <xsl:apply-templates select="@* | node()"/> > </xsl:copy> > </xsl:template> > <!-- > ========================================================= > --> > <!-- Function: Bin2Dec(<value>) => Decimal value > --> > <!-- Parameters:- > --> > <!-- <value> - the binary string to be > converted to decimal --> > <xsl:template name="Bin2Dec"> > <xsl:param name="value" select="'0'"/> > <!-- the following paremeters are used only > during recursion --> > <xsl:param name="bin-power" select="number(1)"/> > <xsl:param name="accum" select="number(0)"/> > <!-- isolate last binary digit --> > <xsl:variable name="bin-digit" > select="substring($value,string-length($value),1)"/> > <!-- check that binary digit is valid --> > <xsl:choose> > <xsl:when > test="not(contains('01',$bin-digit))"> > <!-- not a binary digit! --> > <xsl:text>NaN</xsl:text> > </xsl:when> > <xsl:when test="string-length($bin-digit) = > 0"> > <!-- unexpected end of hex string --> > <xsl:text>0</xsl:text> > </xsl:when> > <xsl:otherwise> > <!-- OK so far --> > <xsl:variable name="remainder" > select="substring($value,1,string-length($value)-1)"/> > <xsl:variable name="this-digit-value" > select="number($bin-digit) * $bin-power"/> > <!-- determine whether this is the end of > the hex string --> > <xsl:choose> > <xsl:when test="string-length($remainder) > = 0"> > <!-- end - output final result --> > <xsl:value-of select="$accum + > $this-digit-value"/> > </xsl:when> > <xsl:otherwise> > <!-- recurse to self for next digit --> > <xsl:call-template name="Bin2Dec"> > <xsl:with-param name="value" > select="$remainder"/> > <xsl:with-param name="bin-power" > select="$bin-power * 2"/> > <xsl:with-param name="accum" > select="$accum + $this-digit-value"/> > </xsl:call-template> > </xsl:otherwise> > </xsl:choose> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > > Cheers, > > Jarno
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Create a bit mask ?, Jarno.Elovirta | Thread | [xsl] build a select clause or dyna, Andy Dent |
Re: [xsl] XPath to match attribute , Matt Dittbenner | Date | Re: [xsl] XPath to match attribute , Emmanouil Batsis |
Month |