在Powershell中解析html实体

时间:2014-05-07 16:20:44

标签: html xml powershell tfs

我通过Powershell使用Microsoft Team Foundation Server。 我想要做的任务是获取和设置“测试用例”类型的给定工作项的“步骤”。

由于某些我不了解的原因,TFS将 HTML in XML 等信息存储在其中,其中HTML元素是使用 HTML实体编写的,以免弄乱XML。

以下是一个例子:

<steps id="0" last="3">
    <step id="2" type="ValidateStep">
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;P&gt;I do this and that&lt;/P&gt;&lt;/DIV&gt;
        </parameterizedString>
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;
        </parameterizedString>
        <description/>
    </step>
    <step id="3" type="ActionStep">
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;DIV&gt;&lt;P&gt;I do something else &lt;BR/&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;
        </parameterizedString>
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;P&gt;This happens &lt;BR/&gt;&lt;/P&gt;&lt;/DIV&gt;
        </parameterizedString>
        <description/>
    </step>
</steps>

其中显示为: Screenshot of how TFS renders the steps for the test case

如何获得每件商品的“裸文”?例如,This happens中的&lt;DIV&gt;&lt;P&gt;This happens &lt;BR/&gt;&lt;/P&gt;&lt;/DIV&gt;。 我是否必须编写自己的解析器,或者我已经可以使用它了吗?

1 个答案:

答案 0 :(得分:1)

System.Web命名空间中的某些内容可以帮助您:

PS> add-type -AssemblyName system.web
PS> [System.Web.HttpUtility]::HtmlDecode("Baskin &amp; Robbins")
Baskin & Robbins

<强>更新

我再次阅读你的问题,你想要更多。如果你不熟悉xml和html语义,那就有点棘手了,所以这里有一个脚本,我把它拼凑在了一起。我希望你能根据自己的需要进行修改。

add-type -AssemblyName system.web

$raw = @'
<steps id="0" last="3">
    <step id="2" type="ValidateStep">
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;P&gt;I do this and that&lt;/P&gt;&lt;/DIV&gt;
        </parameterizedString>
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;
        </parameterizedString>
        <description/>
    </step>
    <step id="3" type="ActionStep">
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;DIV&gt;&lt;P&gt;I do something else &lt;BR/&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;
        </parameterizedString>
        <parameterizedString isformatted="true">
            &lt;DIV&gt;&lt;P&gt;This happens &lt;BR/&gt;&lt;/P&gt;&lt;/DIV&gt;
        </parameterizedString>
        <description/>
    </step>
</steps>
'@

$xml = [xml]$raw

$xml.steps.step | foreach-object { 
  write-host ('Processing {0}...' -f $_.type)

  $_.parameterizedString | foreach-object {
    # decode html entities
    $html = [System.Web.HttpUtility]::HtmlDecode($_.innerText)

    # let's hope the html is balanced and valid xhtml (matching begin/end tags)
    # assumption is that the innermost <P> wraps the desired text
    # match with xpath
    $text = ([xml]$html).SelectSingleNode('//P/text()').value

    write-host "Text: '$text'"
  }
}