2016-07-22 131 views
1

我使用PowerShell递归地替换XML文件中的文本。该脚本在替换中工作正常。但是,XML文件也具有不应该被替换的文件路径。这是剧本目前正在使用XML文件中的条件替换

if ($content -match ' web site | web-site ') { 
    $content -replace ' web site ',' New Site ' -replace ' web-site ',' New Site ' | 
     Out-File $file.FullName -Encoding utf8 

例如,如果XML文件有

<title>web site</title> 
<subtitle>web-site</subtitle> 
<path>c:/web site/website.xml</path> 

预期的输出应该如下。文件路径中的匹配文本应该被忽略。如何添加一个条件来忽略该字符串,如果它在/web site//web-site.xml之间?

<title>New Site</title> 
<subtitle>New Site</subtitle> 
<path>c:/web site/website.xml</path> 

回答

0

这里有一个速战速决,但请注意,一个更强大的解决方案将使用PowerShell的XML解析功能:看Ansgar Wiecher's helpful answer

注:
- 这个回答假设的琴弦兴趣不与XML文档的语法元素相冲突,例如元素名称和属性名称(这恰好适用于特定字符串),这说明了为什么使用真正的XML解析器是更好的选择。

$content = @' 
<doc> 
<title>web site</title> 
<subtitle>web-site</subtitle> 
<path>c:/web site/website.xml</path> 
</doc> 
'@ 

$modifiedContent = $content -replace '(^|[^/])web[ -]site([^/]|$)', '$1New Site$2' 
# Replace 'web site' and 'web-site' if not preceded or followed by a '/'. 
# Note: `web[ -]site` is the equivalent of `web site|web-site` 

if ($modifiedContent -cne $content) { # If contents have changed, save. 
    Out-File -InputObject $modifiedContent $file.FullName -Encoding utf8 
} 
+0

@Ansgar和mklement有出现在那里将与前文太喜欢后有空格'新网站'这就是为什么我想知道是否有任何快速修复忽略/文本/任何正则表达式。是否有任何quickfix的狐狸为此,或者你可以给我一个领导来处理这个XML解析 – user2628187

+0

@ user2628187:请参阅我的更新。 Ansgar的回答专门针对'title'和'subtitle'元素,所以我希望它能够按原样运行(除非你不想使用明确的元素名称列表)。 – mklement0

4

它通常是更为有效和很不容易出错来处理XML作为XML。选择要更新的节点,然后将修改的数据保存回文件。

$filename = 'C:\path\to\your.xml' 

[xml]$xml = Get-Content $filename 
$xml.SelectNodes('//*[self::title or self::subtitle]') | 
    Where-Object { $_.'#text' -match 'web.site' } | 
    ForEach-Object { $_.'#text' = 'New Site' } 
$xml.Save($filename) 

如果您需要修改节点文本串,你可以做这样的事情:

$filename = 'C:\path\to\your.xml' 

[xml]$xml = Get-Content $filename 
$xml.SelectNodes('//*[self::title or self::subtitle]') | 
    Where-Object { $_.'#text' -match 'web.site' } | 
    ForEach-Object { $_.'#text' = $_.'#text' -replace 'web.site', 'New Site' } 
$xml.Save($filename) 
+1

做得很好;我建议使用'-match'web [ - ] site''来更加精确地匹配OP的代码;你有使用'self ::'的特殊原因吗?似乎没有它工作正常。 – mklement0

+1

我还没有意识到它的工作原理没有'self'轴。 –

+0

是的,但问题是文件路径可能出现在许多不同的xml标记中,因此无法使用此选项。你知道我们是否可以用正则表达式的形式指定前一个和最后一个文本,比如前/后的slach/web site/ – user2628187