简体   繁体   English

使用通配符替换XSL中的文本

[英]Replace text in XSL using wildcards

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. 我正在使用由数码摄像机生成的XML文件。 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. 相机允许用户将所有相机的设置保存到SD卡,以便可以调用设置或将其加载到另一台相机中。 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. 我正在编写的XSL样式表将允许用户查看相机的设置,如在Web浏览器中保存到SD卡中。

While most of the values in the XML file -- as formatted by my stylesheet -- make sense to humans, some do not. 虽然XML文件中的大多数值(由我的样式表格式化)对人类有意义,但有些则不然。 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. 我想要做的是让样式表显示文本基于XML文件中的值,但人类更容易理解。

A typical value that can be written to the XML file is "_23_970" which represents the camera's frame rate. 可以写入XML文件的典型值是“_23_970”,表示摄像机的帧速率。 This would be better displayed as 23.970 (or 023.970). 这将更好地显示为23.970(或023.970)。 The first underscore is a sort of place holder to make a space for values over 099.999. 第一个下划线是一种占位符,为超过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). 但是,在这种情况下,相机可以设置为119,999帧速率中的任何一个(我想我的数学运算正确)。

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). 我想,这种方法是将值传递给显示的网页,该网页保存数值(每个数字),用小数替换第二个下划线,并用nbsp或0替换第一个下划线(以较为简单的方式) )。 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. 如果字符串中的第一个字符是“1”(相机可以以高达120.000的帧速率运行),则应将该字符传递给样式表显示的页面。

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: 我应该向您展示在XSL文件中显示文本的代码:

<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 我还应该为您提供我一直使用的示例文件的URL: http//josephthomas.info/Alexa/Setup_120511_140322.xml

Assuming the element with those values is named frame-rate the following uses templates to handle to two cases: 假设具有这些值的元素被命名为frame-rate ,以下使用模板来处理两种情况:

<xsl:template match="frame-rate[starts-with(., '_')]">
  <xsl:value-of select="concat('&#160;', translate(substring(., 2), '_', '.'))"/>
</xsl:template>

<xsl:template match="frame-rate[not(starts-with(., '_'))]">
  <xsl:value-of select="translate(., '_', '.')"/>
</xsl:template>

Use : 用途

concat(translate(substring(.,1,1), '_', '&#xA0;'),
       translate(substring(.,2), '_', '.')
      )

Here is a complete transformation: 这是一个完整的转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>
 <xsl:template match=
  "td[preceding-sibling::*[1][self::td and . = 'Frame Rate']]/text()">
  <xsl:value-of select=
   "concat(translate(substring(.,1,1), '_', '&#xA0;'),
           translate(substring(.,2), '_', '.')
          )
   "/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on a simple XML document that contains one actual tr element (and one added to test the second case) from the actual XML document as pointed to by the provided link : 当这个转换应用于一个简单的XML文档时,该文档包含一个实际的tr元素(以及一个用于测试第二种情况的元素),它来自实际的XML文档,如提供的链接所指示的

<t>
    <tr>
        <td class="title_column">Frame Rate</td>
        <td>_23_976</td>
    </tr>
    <tr>
        <td class="title_column">Frame Rate</td>
        <td>118_235</td>
    </tr>
</t>

the wanted, correct result is produced: 产生了想要的正确结果:

<t>
   <tr>
      <td class="title_column">Frame Rate</td>
      <td> 23.976</td>
   </tr>
   <tr>
      <td class="title_column">Frame Rate</td>
      <td>118.235</td>
   </tr>
</t>

Explanation : 说明

The expression: 表达方式:

concat(translate(substring(.,1,1), '_', '&#xA0;'),
       translate(substring(.,2), '_', '.')
      )

is evaluated in the following way: 按以下方式评估:

  1. The two arguments of the concat() function are evaluated separately (independently from each other). concat()函数的两个参数是分开计算的(彼此独立)。

  2. concat() does what it name implies -- concatenates its two string arguments into a single string. concat()做它的名字暗示 - 将它的两个字符串参数连接成一个字符串。

  3. The translate() function is referenced twice in this expression -- it is used to produce each of the arguments of `concat(). translate()函数在此表达式中被引用两次 - 它用于生成`concat()的每个参数。

  4. The first call of translate() is: translate(substring(.,1,1), '_', '&#xA0;') . translate()的第一个调用是: translate(substring(.,1,1), '_', '&#xA0;') 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 . ). 在这种情况下传递给函数的第一个参数是当前节点的字符串值的前导字符(在XPath中,当前(或上下文)节点由.表示)。 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 to translate() is a string containing all the characters that we want to replace or delete -- in this case just the single "_" character. 这个前导字符由函数调用产生: substring(.,1,1) ,它取一个从offset 1开始并且长度为1的子字符串 。对translate()这个调用的第二个参数是一个包含所有字符的字符串我们想要替换或删除 - 在这种情况下只是单个"_"字符。 The third argument to translate() is a string of "replacement characters" that should substitute the corresponding (by position) characters in the second argument. translate()的第三个参数是一个“替换字符”字符串,它应该替换第二个参数中相应的(按位置)字符。 In this casethe third argument contains the single character '&#xA0;' 在这种情况下,第三个参数包含单个字符'&#xA0;' (nbsp), this means that the call to the translate() function will replace the first character of the string value of the current node with nbsp if it happens to be an underscore. (nbsp),这意味着对translate()函数的调用将替换当前节点的字符串值的第一个字符( 如果恰好是下划线)。

  5. The second call of translate() is similar to the first call: translate(substring(.,2), '_', '.') . translate()的第二次调用类似于第一次调用: 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. 但是,它应用于当前节点的字符串值的其余部分(从位置2开始),并用点字符替换此余数中的任何下划线。

Update : 更新

As the OP has difficulties in understanding how to adjust this solution to his own code. 由于OP难以理解如何根据自己的代码调整此解决方案。 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): 这是我的猜测(因为他的源XML文档不是提供的链接指向的那个,我无法猜出真正的XML文档是什么):

<tr>
    <xsl:for-each select="Settings/Groups/Recording">
        <tr>
            <td class="title_column">Frame Rate</td>
            <td>
          <xsl:value-of select=
           "concat(translate(substring(RecOutLinkSpeed,1,1), '_', '&#xA0;'),
                   translate(substring(RecOutLinkSpeed,2), '_', '.')
                  )
           "/>
            </td>
        </tr>
    </xsl:for-each>
</tr>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM