带有 XPath 正则表达式的字符串的小写部分 [英] Lowercase part of a string with XPath regular expression

查看:84
本文介绍了带有 XPath 正则表达式的字符串的小写部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个节点中,一个字符串可能包含一个或多个由单引号或双引号分隔的子字符串.例如

In a node, a string might contain one or more substrings delimited by single or double quotes. For example

<node>Some text "and Some" More</node>

我要做的是将没有被引号括起来的文本小写,所以结果应该是:

What I have to do is lowercase the text that is not surrounded by quotes, so the result should look as:

some text "and Some" more

我尝试了两件事:

  1. with replace: replace('Some text "and Some" More', '"([^"]*)"', '*') 这将用 * 替换双引号中的文本.但是我怎么能把它小写呢?这不会产生预期的结果: replace('Some text "and Some" More', '"([^"]*)"', 小写('$1'))
  2. with tokenize: for $t in tokenize('Some text "and Some" More', '"') return $t.因为我的节点会not 以 " 开头,我知道奇数条目将是用引号括起来的子字符串.但我不知道如何选择和小写只有奇数条目.我尝试使用 position() 但它在每次迭代时返回 1.
  1. with replace: replace('Some text "and Some" More', '"([^"]*)"', '*') this will replace the text in double quotes with *. But how can I lowercase it? This doesn't produce the desired result: replace('Some text "and Some" More', '"([^"]*)"', lower-case('$1'))
  2. with tokenize: for $t in tokenize('Some text "and Some" More', '"') return $t. Since my node will not start with ", I know the odd entries will be the substrings surrounded by quotes. But I don't know how to choose and lower-case only the odd entries. I tried with position() but it returns 1 on each iteration.

感谢您对此进行调查.非常感谢.

Thanks for looking into this. Much appreciated.

推荐答案

这是一个单一的 XPath 2.0 表达式,它以所需的方式处理带引号和不带引号的字符串的任何混合 -- 以任何顺序:

  string-join(
  (for $str in tokenize(replace(., "(.*?)("".*?"")([^""]*)", "|$1|$2|$3|", "x"),"\|")
     return
      if(not(contains($str, """")))
        then lower-case($str)
        else $str
  ),
  "")

为了全面测试,我在以下 XML 文档上评估上述表达式:

<node>Some "Text""and Some" More "Text" XXX "Even More"</node>

产生了想要的、正确的结果:

some "Text""and Some" more "Text" xxx "Even More"

<小时>

XSLT 2.0 验证:

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

 <xsl:template match="/">
  <xsl:sequence select=
  'string-join(
  (for $str in tokenize(replace(., "(.*?)("".*?"")([^""]*)", "|$1|$2|$3|", "x"),"\|")
     return
      if(not(contains($str, """")))
        then lower-case($str)
        else $str
  ),
  "")
  '/>
 </xsl:template>
</xsl:stylesheet>

当这个转换应用于上述 XML 文档时,XPath 表达式被计算,这个计算的结果被复制到输出:

some "Text""and Some" more "Text" xxx "Even More"

<小时>

最后,XSLT 2.0 解决方案——更容易编写和理解:

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

 <xsl:template match="/*">
  <xsl:analyze-string select="." regex='".*?"'>
   <xsl:non-matching-substring>
     <xsl:sequence select="lower-case(.)"/>
   </xsl:non-matching-substring>
   <xsl:matching-substring><xsl:sequence select="."/></xsl:matching-substring>
  </xsl:analyze-string>
 </xsl:template>
</xsl:stylesheet>

这篇关于带有 XPath 正则表达式的字符串的小写部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆