我正在使用PowerShell以递归方式替换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 :(得分: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 :(得分:0)
以下是快速修复,但请注意更强大的解决方案将使用PowerShell的XML解析功能:请参阅Ansgar Wiecher's helpful answer:
注意:
- 这个答案假设感兴趣的字符串不与XML文档的语法元素冲突,例如元素名称和属性名称(这恰好适用于所讨论的特定字符串),这说明了原因使用真正的XML解析器是更好的选择。
template<typename T, size_t S>
struct Vec;
template<typename T>
struct Vec<T, 1> {
enum {count = 1};
T x;
T& operator[](size_t i) {
assert(i == 0);
return x;
}
const T& operator[](size_t i) const {
assert(i == 0);
return x;
}
};
template<typename T>
struct Vec<T, 2> {
enum { count = 2 };
T x;
T y;
T& operator[](size_t i) {
assert(0 <= i && i < count);
return this->*(pointer(i));
}
const T& operator[](size_t i) const {
assert(0 <= i && i < count);
return this->*(pointer(i));
}
static T Vec::* pointer(size_t i) {
static T Vec::* a[count] = { &Vec::x, &Vec::y };
return a[i];
}
};
template<typename T>
struct Vec<T, 3> {
enum { count = 3 };
T x;
T y;
T z;
T& operator[](size_t i) {
assert(0 <= i && i < count);
return this->*(pointer(i));
}
const T& operator[](size_t i) const {
assert(0 <= i && i < count);
return this->*(pointer(i));
}
static T Vec::* pointer(size_t i) {
static T Vec::* a[count] = { &Vec::x, &Vec::y, &Vec::z };
return a[i];
}
};
int main() {
Vec<int, 2> v1{ 1, 2 };
assert(v1[0] == v1.x);
assert(v1[1] == v1.y);
Vec<unsigned char, 3> v2{ 4, 5, 6 };
assert(v2[0] == v2.x);
assert(v2[1] == v2.y);
assert(v2[2] == v2.z);
return 0;
}