如何在PowerShell中有效地修改HTML字符串?

0pizxfdo  于 2023-03-12  发布在  Shell
关注(0)|答案(1)|浏览(168)

我有这段PowerShell代码。

$html = @"
<table>
    <colgroup><col/><col/><col/><col/><col/><col/></colgroup>
    <tr><td>447.1</td><td>365.5</td><td>81.6</td><td>81.8</td></tr>
    <tr><td>953.9</td><td>412.7</td><td>541.2</td><td>43.3</td></tr>
    <tr><td>953.3</td><td>145.2</td><td>808.1</td><td>15.2</td></tr>
    <tr><td>1,863.0</td><td>1,466.4</td><td>396.6</td><td>78.7</td></tr>
    <tr><td>1,863.0</td><td>863.9</td><td>999.1</td><td>46.4</td></tr>
    <tr><td>931.5</td><td>183.1</td><td>748.4</td><td>19.7</td></tr>
</table>
"@

我如何添加一个类“cls1”到第1、3和4列?有没有类似JavaScript的方法?我现在不想用正则表达式解析它。

roejwanj

roejwanj1#

您所拥有的是有效的XHTML,因此可以使用.NET XML parser

# Create an instance of XmlDocument (alias [xml])
$xml = [xml]::new(); $xml.PreserveWhitespace = $true

# Parse the XHTML string
$xml.LoadXml( $html )

foreach( $row in $xml.table.tr ) {
    $row.ChildNodes | Where-Object Name -eq 'td' | 
        Select-Object -Index 0,2,3 | 
        ForEach-Object { $_.SetAttribute('class','cls1') }
}

$xml.OuterXml

输出:

<table>
    <colgroup><col /><col /><col /><col /><col /><col /></colgroup>
    <tr><td class="cls1">447.1</td><td>365.5</td><td class="cls1">81.6</td><td class="cls1">81.8</td></tr>
    <tr><td class="cls1">953.9</td><td>412.7</td><td class="cls1">541.2</td><td class="cls1">43.3</td></tr>
    <tr><td class="cls1">953.3</td><td>145.2</td><td class="cls1">808.1</td><td class="cls1">15.2</td></tr>
    <tr><td class="cls1">1,863.0</td><td>1,466.4</td><td class="cls1">396.6</td><td class="cls1">78.7</td></tr>
    <tr><td class="cls1">1,863.0</td><td>863.9</td><td class="cls1">999.1</td><td class="cls1">46.4</td></tr>
    <tr><td class="cls1">931.5</td><td>183.1</td><td class="cls1">748.4</td><td class="cls1">19.7</td></tr>
</table>

备注:

  • $xml.table.tr ...使用member access enumeration深入XML树,创建<tr>元素数组
  • 要访问<td>元素,我们不能使用.td成员访问,因为PowerShell将只包含文本的元素转换为简单字符串。但我们需要一个XmlElement,以便能够通过其SetAttribute方法设置属性。因此,我们必须使用.ChildNodes属性。
  • Where-Object按名称过滤子节点,以增强健壮性。
  • Select-Object -Index为我们提供了指定列索引处的<td>元素。
  • ForEach-Object处理每个选定的<td>元素。在脚本块{…}中,$_变量表示当前元素,并允许使用调用.NET .SetAttribute方法。

相关问题