This is similar to an earlier problem I was having which you guys solved in less than a day.
I am working with XML files that are generated by a digital video camera. The camera allows the user to save all of the camera’s settngs to an SD card so that the settings can be recalled or loaded into another camera. The XSL stylesheet I am writing will allow users to view the camera’s settings, as saved to the SD card in a web browser.
While most of the values in the XML file — as formatted by my stylesheet — make sense to humans, some do not. What I would like to do is have the stylesheet display text that is based on the value in the XML file but more easily understood by humans.
A typical value that can be written to the XML file is “_23_970” which represents the camera’s frame rate. This would be better displayed as 23.970 (or 023.970). The first underscore is a sort of place holder to make a space for values over 099.999. The second underscore, obviously represents the decimal.
My previous (similar) question involved replacing predictable text, and the solution was matching templates. In this case, however, the camera can be set at any one of 119,999 frame rates (I think I did that math correctly).
The approach, I would guess, is to pass a value to the displayed webpage that keeps the numeric values (each digit), replaces the second underscore with a decimal, and replaces the first underscore with either an nbsp or a zero (whichever is easier). If the first character in the string is a “1” (the camera can run at frame rates up to 120.000) then the one should be passed on to the page displayed by the stylesheet.
I have read other posts here regarding wildcards, but couldn’t find one that answered this question.
EDIT: Sorry for leaving out important info. I fared better on my first try at asking a question! I guess I got complacent. Anyhow . . .
I should have shown you the code that displays the text in the XSL file as is:
<tr>
<xsl:for-each select="Settings/Groups/Recording">
<tr><td class="title_column">Frame Rate</td><td><xsl:value-of select="RecOutLinkSpeed"/></td></tr>
</xsl:for-each>
</tr>
I should also have given you the URL for the sample file I have been working with: http://josephthomas.info/Alexa/Setup_120511_140322.xml
Use:
Here is a complete transformation:
When this transformation is applied on a simple XML document that contains one actual
trelement (and one added to test the second case) from the actual XML document as pointed to by the provided link:the wanted, correct result is produced:
Explanation:
The expression:
is evaluated in the following way:
The two arguments of the
concat()function are evaluated separately (independently from each other).concat()does what it name implies — concatenates its two string arguments into a single string.The
translate()function is referenced twice in this expression — it is used to produce each of the arguments of `concat().The first call of
translate()is:translate(substring(.,1,1), '_', ' '). The first argument that is passed to the function in this case is the leading character of the string value of the current node (in XPath the current (or context) node is denoted by.). This leading character is produced by the function call:substring(.,1,1)which takes a substring starting at offset 1 and having length of 1. The second argument to this call totranslate()is a string containing all the characters that we want to replace or delete — in this case just the single"_"character. The third argument totranslate()is a string of “replacement characters” that should substitute the corresponding (by position) characters in the second argument. In this casethe third argument contains the single character' '(nbsp), this means that the call to thetranslate()function will replace the first character of the string value of the current node with nbsp if it happens to be an underscore.The second call of
translate()is similar to the first call:translate(substring(.,2), '_', '.'). However it is applied to the remainder of the current node’s string value (starting from position 2) and replaces any underscore in this remainder with the dot character.Update:
As the OP has difficulties in understanding how to adjust this solution to his own code. here is my guess (as his source XML doccument isn’t the one pointed by the provided link and I cannot guess what the real XML document is):