2014-04-01 120 views
0

如何从PowerShell中的XML文档获取多个文本元素?从XML获取多个文本元素

下面是一个例子:

<log> 
    <logentry revision="152"> 
    <author>me</author> 
    <date>2014-03-28T14:54:27.443978Z</date> 
    <msg>Summary 1 

* Note 1 
* Note 2</msg></logentry> 
    <logentry revision="153"> 
    <author>me</author> 
    <date>2014-03-28T16:24:43.438847Z</date> 
    <msg>Summary 2</msg> 
    </logentry> 
    <logentry revision="154"> 
    <author>me</author> 
    <date>2014-03-31T16:00:01.590373Z</date> 
    <msg>Summary 3</msg> 
    </logentry> 
    <logentry revision="155"> 
    <author>me</author> 
    <date>2014-04-01T09:28:09.744015Z</date> 
    <msg>Summary 4 

* Note 3 
* Note 4 
    </msg> 
    </logentry> 
</log> 

这是svn log特定版本的输出。自从上一个脚本运行手动汇总到文本文件以来,我想简化日志消息。我可以读取现有文件,解析上一个修订版本并为新版本调用svn log。我想获得以上XML文档中的下列文本输出:

Summary 1 
* Note 1 
* Note 2 
Summary 2 
Summary 3 
Summary 4 
* Note 3 
* Note 4 

还要注意在每个“logentry /味精”元素的不一致最终换行符。所有空行都应该被删除,但所有其他换行必须保留。另外,每个“msg”元素必须放在一个新行中,而不是将多个消息粘贴在一个输出行中(现在我已经有了)。

这里是我当前的代码:

$newMsgs = ($xml.log.logentry.msg).Replace("`n`n", "`n").Trim() 

但它并不把每个“味精”,在一个单独的行。此外,我不明白它究竟发生了什么,什么时候会中断。我熟悉C#中的BCL,但不是那么多的PowerShell和它自己的解决方法。

回答

2

你可以很容易地将消息拆分到新行字符上,然后过滤掉没有任何内容的行。如果你想删除只包含空格的行,你可以在过滤之前修剪它们。这里有一个例子:

$xml.log.logentry.msg -split "`n" | Foreach { $_.Trim() } | Where { $_ } 

作为一个方面说明,你有一个小样本XML错误。第一个msg元素永远不会关闭。

下面是一个使用示例XML和过滤使用上面的脚本一个完整的示例:

[xml]$xml = @" 
<log> 
    <logentry revision="152"> 
    <author>me</author> 
    <date>2014-03-28T14:54:27.443978Z</date> 
    <msg>Summary 1 

* Note 1 
* Note 2</msg> 
    </logentry> 
    <logentry revision="153"> 
    <author>me</author> 
    <date>2014-03-28T16:24:43.438847Z</date> 
    <msg>Summary 2</msg> 
    </logentry> 
    <logentry revision="154"> 
    <author>me</author> 
    <date>2014-03-31T16:00:01.590373Z</date> 
    <msg>Summary 3</msg> 
    </logentry> 
    <logentry revision="155"> 
    <author>me</author> 
    <date>2014-04-01T09:28:09.744015Z</date> 
    <msg>Summary 4 

* Note 3 
* Note 4 
    </msg> 
    </logentry> 
</log> 
"@ 

$xml.log.logentry.msg -split "`n" | Foreach { $_.Trim() } | Where { $_ } 

这就产生所需的输出:

Summary 1 
* Note 1 
* Note 2 
Summary 2 
Summary 3 
Summary 4 
* Note 3 
* Note 4 
+0

的XML错误必须是一个错字,因为我已经复制它脱离了控制台窗口。所以你的命令给了我一串字符串,我想每行一个。我怎样才能将它转换成一个带有一致的换行符的字符串,并将它与以前的内容一起写回文件? – ygoe

+0

你想把它加回到XML中,然后保存?当你说“一致的换行符”时,你是否期望回车换行和换行符,或者只是换行符,或者不管它是混合还是混合,只要它们位于正确的位置? –

+0

不,我只是使用XML作为源代码,但是将所有内容写入纯文本文件。 SVN也可以给我纯文本,但XML应该更安全的解析。我更喜欢CRLF,因为这是Windows使用的,SVN似乎只返回LF。现在我有两个丑陋的混合,并且在“味精”项目之间缺少换行符。但是用一些Replace()调用来清理已存在的换行符应该很容易。 – ygoe