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

时间:2012-06-22 17:06:00

标签: xml xslt

这与我之前遇到的早期问题类似,你们不到一天就解决了这个问题。

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

虽然XML文件中的大多数值(由我的样式表格式化)对人类有意义,但有些则不然。我想要做的是让样式表显示文本基于XML文件中的值,但人们更容易理解。

可以写入XML文件的典型值是“_23_970”,表示摄像机的帧速率。这将更好地显示为23.970(或023.970)。第一个下划线是一种占位符,为超过099.999的值创建空间。第二个下划线,显然代表小数。

我之前(类似)的问题涉及替换可预测的文本,解决方案是匹配模板。但是,在这种情况下,相机可以设置为119,999帧速率中的任何一个(我想我的数学运算正确)。

我猜,这种方法是将值传递给显示的网页,该网页保存数值(每个数字),用小数替换第二个下划线,并用nbsp或0替换第一个下划线(哪个更容易)。如果字符串中的第一个字符是“1”(相机可以以高达120.000的帧速率运行),则应将该字符传递给样式表显示的页面。

我在这里读过有关通配符的其他帖子,但找不到回答这个问题的帖子。

编辑:很抱歉遗漏重要信息。我第一次尝试提问时表现得更好!我想我自满了。无论如何。 。

我应该向您展示在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>

我还应该为您提供我一直使用的示例文件的网址:http://josephthomas.info/Alexa/Setup_120511_140322.xml

2 个答案:

答案 0 :(得分:3)

假设具有这些值的元素名为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>

答案 1 :(得分:1)

使用

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

这是一个完整的转型:

<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>

当这个转换应用于一个简单的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>

产生了想要的正确结果:

<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>

<强>解释

表达式:

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

按以下方式评估:

  1. concat() 函数的两个参数分别进行评估(彼此独立)。

  2. concat()执行其名称所暗示的内容 - 将其两个字符串参数连接成一个字符串。

  3. translate() 函数在此表达式中被引用两次 - 它用于生成`concat()的每个参数。

  4. translate()的第一个电话是:translate(substring(.,1,1), '_', '&#xA0;')。在这种情况下传递给函数的第一个参数是当前节点的字符串值的前导字符(在XPath中,当前(或上下文)节点由.表示)。这个前导字符由函数调用生成:substring(.,1,1)从<1>} 开始,偏移量为1,长度为1.此调用的第二个参数为{{1包含我们要替换或删除的所有字符的字符串 - 在本例中只是单个translate()字符。 "_"的第三个参数是一个“替换字符”字符串,它应该替换第二个参数中相应的(按位置)字符。在这种情况下,第三个参数包含单个字符translate()(nbsp),这意味着对'&#xA0;'函数的调用将用nbsp 替换当前节点的字符串值的第一个字符它恰好是一个下划线。

  5. translate()的第二次通话与第一次通话类似:translate()。但是它应用于当前节点的字符串值的其余部分(从位置2开始),并用点字符替换此余数中的任何下划线。

  6. <强>更新

    由于OP难以理解如何根据自己的代码调整此解决方案。这是我的猜测(因为他的源XML文档不是提供的链接指向的那个,我无法猜出真正的XML文档是什么):

    translate(substring(.,2), '_', '.')