选择性地格式化PowerShell管道中的数据并以HTML输出的技术 [英] Technique for selectively formatting data in a PowerShell pipeline and output as HTML

查看:214
本文介绍了选择性地格式化PowerShell管道中的数据并以HTML输出的技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您想对powershell中的某些表格输出进行一些花哨的格式化,目标是html(无论是对于网络服务器,还是通过电子邮件发送)。让我们举个例子,你想要某些数值有不同的背景颜色。随你。我可以想到两种可靠的编程方式来实现这一点:输出XML和使用XSLT转换,或输出HTML和用CSS装饰。

Say that you want to do some fancy formatting of some tabular output from powershell, and the destination is to be html (either for a webserver, or to be sent in an email). Let's say for example that you want certain numeric values to have a different background color. Whatever. I can think of two solid programmatic ways to accomplish this: output XML and transform with XSLT, or output HTML and decorate with CSS.

XSLT可能更难(我说,因为我不知道它),但从什么小我记得,它有能够嵌入选择标准(xpath?)为上述花式格式化的好处。 CSS另一方面需要一个帮助手。如果你想要一个特定的单元格被特别对待,那么你将需要区别它的兄弟姐妹与一个类,id,或沿着这些线条的东西。 PowerShell实际上没有办法做本机,所以这将意味着解析HTML,因为它离开convertto-html和添加,例如,一个强调类:

XSLT is probably the harder of the two (I say that because I don't know it), but from what little I recall, it has the benefit of bring able to embed the selection criteria (xpath?) for aforementioned fancy formatting. CSS on the other hand needs a helping hand. If you wanted a certain cell to be treated specially, then you would need to distinguish it from its siblings with a class, id, or something along those lines. PowerShell doesn't really have a way to do that natively, so that would mean parsing the HTML as it leaves convertto-html and adding, for example, a "emphasis" class:

<td class="emphasis">32MB</td>

我不喜欢所需的文本解析的想法,特别是因为我宁愿能以某种方式强调在Powershell之前需要强调的是什么,然后才会打开HTML。

I don't like the idea of the required text parsing, especially given that I would rather be able to somehow emphasize what needs emphasizing in Powershell before it hits HTML.

XSLT是最好的方法吗?有没有建议如何在离开convertto-html或不同方式的想法之后标记HTML?

Is XSLT the best way? Have suggestions for how to markup the HTML after it leaves convertto-html or ideas of a different way?

推荐答案

更快的方式:



好的,我保证自己,我不会花时间解决问题了,第二个答案是在我的系统上运行超过10秒,因为它正在做PowerShell中的where东西,而不是在LINQ。

A much faster way:

Ok, I keep promising myself that I won't spend time on solved problems anymore, but ... that switch statement in my second answer was taking over 10 seconds to run on my system, -- because it's doing the "where" stuff in PowerShell instead of in LINQ.

由于PowerShell不支持LINQ,我通过在Add-Type调用中编写一个静态辅助方法来解决它(并将switch语句加速大约1000x):

Since PowerShell doesn't support LINQ, I solved it by writing a static helper method in an Add-Type call (and sped up that switch statement by about 1000x):

Add-Type -Language CSharpVersion3 -ReferencedAssemblies System.Xml, System.Xml.Linq -UsingNamespace System.Linq -Name XUtilities -Namespace Huddled -MemberDefinition @"    
    public static System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement> GetElementByIndex( System.Xml.Linq.XContainer doc, System.Xml.Linq.XName element, int index) {
        return from e in doc.Descendants(element) where e.NodesBeforeSelf().Count() == index select e;
    }
    public static System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement> GetElementByValue( System.Xml.Linq.XContainer doc, System.Xml.Linq.XName element, string value) {
        return from e in doc.Descendants(element) where e.Value == value select e;
    }
"@

# Get the running processes to x(ht)ml
$xml = [System.Xml.Linq.XDocument]::Parse( "$(Get-Process | ConvertTo-Html)" )

# Find the index of the column you want to format:
$wsIndex = [Huddled.XUtilities]::GetElementByValue( $xml, "{http://www.w3.org/1999/xhtml}th", "WS" ) | %{ ($_.NodesBeforeSelf() | Measure).Count }


switch([Huddled.XUtilities]::GetElementByIndex( $xml, "{http://www.w3.org/1999/xhtml}td", $wsIndex )) {
   {200MB -lt $_.Value } { $_.SetAttributeValue( "style", "background: red;"); continue } 
   {20MB  -lt $_.Value } { $_.SetAttributeValue( "style", "background: orange;"); continue } 
   {10MB  -lt $_.Value } { $_.SetAttributeValue( "style", "background: yellow;"); continue } 
}

# Save the html out to a file
$xml.Save("$pwd/procs2.html")

# Open the thing in your browser to see what we've wrought
ii .\procs2.html



PowerShell 3:



我重命名这个在PowerShell 3后,有人链接到这个职位,你不再需要编译类型得到它快速:

PowerShell 3:

I redid this in PowerShell 3 after someone linked to this post, and you no longer need the compiled types to get it fast:

Add-Type -AssemblyName System.Xml.Linq

$Process = $(Get-Process | Select Handles, NPM, PM, WS, VM, CPU, Id, ProcessName)

$xml = [System.Xml.Linq.XDocument]::Parse( "$($Process | ConvertTo-Html)" )
if($Namespace = $xml.Root.Attribute("xmlns").Value) {
    $Namespace = "{{{0}}}" -f $Namespace
}

# Find the index of the column you want to format:
$wsIndex = [Array]::IndexOf( $xml.Descendants("${Namespace}th").Value, "WS")

foreach($row in $xml.Descendants("${Namespace}tr")){
    switch(@($row.Descendants("${Namespace}td"))[$wsIndex]) {
       {200MB -lt $_.Value } { $_.SetAttributeValue( "style", "background: red;"); continue } 
       {20MB  -lt $_.Value } { $_.SetAttributeValue( "style", "background: orange;"); continue } 
       {10MB  -lt $_.Value } { $_.SetAttributeValue( "style", "background: yellow;"); continue } 
    }
}
# Save the html out to a file
$xml.Save("$pwd/procs1.html")

# Open the thing in your browser to see what we've wrought
ii .\procs2.html

这篇关于选择性地格式化PowerShell管道中的数据并以HTML输出的技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆