首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有XPath的String变量中的单引号

带有XPath的String变量中的单引号
EN

Stack Overflow用户
提问于 2022-09-01 08:18:37
回答 1查看 77关注 0票数 -1

亲爱的Powershell伙计们

我有一个(也许)非常简单的问题,但我不知道如何解决。我想在XPath表示法中使用包含单引号的字符串变量。我使用CMDlet选择-Xml。如果字符串中没有单引号,则Select完全正常工作。但是,如果有一个单引号(例如:不要),它会使我的脚本崩溃。让我给你详细介绍一下。

问题

代码语言:javascript
复制
$Name = "Dont display" ##is working completly fine

(Select-Xml -Path "C:\SomePath\Somexml.xml" -XPath "//q1:Options[q1:Name = '$Name']"  -Namespace $namespace).Node.InnerText  ##is working completly fine

代码语言:javascript
复制
$Name = "Don't display" ##crashes script

(Select-Xml -Path "C:\SomePath\Somexml.xml" -XPath "//q1:Options[q1:Name = '$Name']"  -Namespace $namespace).Node.InnerText  ##crashes script

powershell的错误输出是:

代码语言:javascript
复制
 Select-Xml : '//q1:Options[q1:Name = 'Don't display']' has an invalid token.
    At line:251 char:41
    + ... ing_Name = (Select-Xml -Path "C:\SomePath\Somexml.xml" -XPath ...
    +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Select-Xml], XPathException
        + FullyQualifiedErrorId : System.Xml.XPath.XPathException,Microsoft.PowerShell.Commands.SelectXmlCommand

到目前为止我尝试了什么,

当然,我尝试过不同的引语,例如:

代码语言:javascript
复制
 $Name = """Don't display"""
 $Name = '"Don't display"'
 $Name = "'Don't display'"
 $Name = "'Don't display'"
 $Name = 'Don't display'
$Name = ''Don't display''

看起来,powershell引用规则和XPath表示法可能存在问题。

但也许你们中的任何人都有办法解决这个问题。

非常感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-01 11:05:38

在XPath字符串文本中似乎没有转义字符,因此不能在文字字符串中使用字符串分隔符,因为它终止字符串--即:

代码语言:javascript
复制
$name = "Don't display"

# single quotes:
# //q1:Options[q1:Name = 'Don't display']
#                            ^ terminates string literal

解决具体问题的一个快速(但却天真)的解决方案是,只使用双引号作为分隔符:

代码语言:javascript
复制
$name = "Don't display"

# double quotes:
# //q1:Options[q1:Name = "Don't display"]
#                            ^ *doesn't* terminate string literal

但是,如果您的数据包含双引号呢?然后你又回到了起点..。

代码语言:javascript
复制
$name = "Don""t display"

# double quotes:
# //q1:Options[q1:Name = "Don"t display"]
#                            ^ terminates string literal again

在病态的情况下,如果您的文字包含单引号和双引号,则不能将它们用作分隔符:

代码语言:javascript
复制
$name = "Don't d""isplay"

# single quotes:
# //q1:Options[q1:Name = 'Don't d"isplay']
#                            ^ terminates string literal

# double quotes:
# //q1:Options[q1:Name = "Don't d"isplay"]
#                                ^ also terminates string literal

在这种情况下,您可以求助于this答案,这意味着将字符串文本转换为concat表达式,这样您就可以得到:

代码语言:javascript
复制
$name = "Don't d""isplay"

# //q1:Options[q1:Name = concat('Don', "'", 't d"isplay')]
#                               ^^^^^ use single quotes
#                                      ^^^ use double quotes
#                                           ^^^^^^^^^^^^ use single quotes

您可以通过以下方式生成:

代码语言:javascript
复制
$name = "Don't d""isplay"

$squote = "', `"'`", '"
$expr   = "concat('{0}')" -f $name.Replace("'", $squote)

# Select-Xml -Xml $xml -XPath "//q1:Options[q1:Name = $expr]"
# ->
# //q1:Options[q1:Name = concat('Don', "'", 't d"isplay')]

然后,包含双引号的数据部分用单引号分隔,反之亦然,因此它们都会正确终止。

注意-您可能会对没有一种类型的引号或另一种引用的文字和连续的单引号进行优化,并且需要为$null和其他边缘情况添加一些错误处理,但它基本上可以完成这项工作.

更新

这里有一个完整的代码示例来展示它的作用..。

代码语言:javascript
复制
$xml = [xml] "<root><child Name=`"my'name`" /></root>"

$name = "my'name"

$squote = "', `"'`", '"
$expr   = "concat('{0}')" -f $name.Replace("'", $squote)

Select-Xml -Xml $xml -XPath "//child[@Name = $expr]"

# Node  Path        Pattern
# ----  ----        -------
# child InputStream //child[@Name = concat('my', "'", 'name')]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73566204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档