Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PowerShell管道中选择性格式化数据并输出为HTML的技术_Html_Css_Xml_Powershell - Fatal编程技术网

在PowerShell管道中选择性格式化数据并输出为HTML的技术

在PowerShell管道中选择性格式化数据并输出为HTML的技术,html,css,xml,powershell,Html,Css,Xml,Powershell,假设您想对powershell的一些表格输出进行一些奇特的格式化,目标是html(对于Web服务器或通过电子邮件发送)。例如,假设您希望某些数值具有不同的背景色。无论什么我可以想出两种可靠的编程方法来实现这一点:输出XML并使用XSLT进行转换,或者输出HTML并使用CSS进行装饰 XSLT可能是这两种格式中比较难的(我这么说是因为我不知道它),但据我记忆所及,它的好处是能够为前面提到的格式嵌入选择标准(xpath?)。另一方面,CSS需要帮助。如果你想对某个细胞进行特殊处理,那么你需要用类、i

假设您想对powershell的一些表格输出进行一些奇特的格式化,目标是html(对于Web服务器或通过电子邮件发送)。例如,假设您希望某些数值具有不同的背景色。无论什么我可以想出两种可靠的编程方法来实现这一点:输出XML并使用XSLT进行转换,或者输出HTML并使用CSS进行装饰

XSLT可能是这两种格式中比较难的(我这么说是因为我不知道它),但据我记忆所及,它的好处是能够为前面提到的格式嵌入选择标准(xpath?)。另一方面,CSS需要帮助。如果你想对某个细胞进行特殊处理,那么你需要用类、id或类似的东西来区分它和它的兄弟姐妹。PowerShell实际上没有一种本机方式来实现这一点,因此这意味着在HTML转换为HTML时对其进行解析,并添加(例如)一个“emphasis”类:

32MB
我不喜欢所需的文本解析的想法,尤其是考虑到我更希望能够在Powershell进入HTML之前以某种方式强调它需要强调的内容


XSLT是最好的方法吗?您对如何在HTML转换为HTML或以不同的方式标记HTML有何建议?

如何使用JQuery,插入带有JQuery脚本和一些样式的标题,如:

Get-Process | ConvertTo-Html -Head @'

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {

   $("table tr td:nth-child(" + ( $("table th:contains('WS')").index() + 1 ) + ")").each(function() {
      if($(this).html() > 209715200) { // 200MB
         $(this).css("background", "red" );
      } else if($(this).html() > 20971520) { // 20MB
         $(this).css("background", "orange" );
      } else if($(this).html() > 10485760) { // 10MB
         $(this).css("background", "yellow" );
      }
   });

})
</script>

'@ | Out-File procs.html; ii .\procs.html
Get进程|转换为Html-Head@'
$(文档).ready(函数(){
$($($($($($)表th:contains('WS'))。index()+1)+”)。每个(函数(){
如果($(this.html()>209715200){//200MB
$(this.css(“背景”、“红色”);
}如果($(this.html()>20971520){//20MB
$(this.css(“背景”、“橙色”);
}如果($(this.html()>10485760){//10MB
$(this.css(“背景”、“黄色”);
}
});
})
“@| Out File procs.html;ii.\procs.html

嘿,我想出了另一个我更喜欢的答案。这个不依赖于支持JavaScript的浏览器

Add-Type -AssemblyName System.Xml.Linq

# 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 = (($xml.Descendants("{http://www.w3.org/1999/xhtml}th") | Where-Object { $_.Value -eq "WS" }).NodesBeforeSelf() | Measure-Object).Count

# Format the column based on whatever rules you have:
switch($xml.Descendants("{http://www.w3.org/1999/xhtml}td") | Where { ($_.NodesBeforeSelf() | Measure).Count -eq $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
有没有专门的徽章可以偷取你自己的“标记为答案”的徽章?;-)

更快的方法: 好吧,我一直向自己保证我不会再花时间解决问题了,但是。。。我第二个答案中的switch语句在我的系统上运行需要10秒以上,因为它在PowerShell中而不是在LINQ中执行“where”操作

由于PowerShell不支持LINQ,我通过在Add-Type调用中编写一个静态helper方法解决了这个问题(并将switch语句的速度提高了大约1000倍):


经过一些github讨论,我已经使用
.where()
方法为PowerShell 4/5/6更新了此选项,从而消除了对管道的依赖。缓慢的部分是生成HTML,而实际的XML操作只需要约200毫秒

Add-Type -AssemblyName System.Xml.Linq

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

# Find the index of the column you want to format:
$wsIndex = $xml.Descendants("{http://www.w3.org/1999/xhtml}th").
    Where{$_.Value -eq "WS" }.
        NodesBeforeSelf().
            Count

# Format the column based on whatever rules you have:
switch($xml.Descendants("{http://www.w3.org/1999/xhtml}td").Where{@($_.NodesBeforeSelf()).Count -eq $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

你的要求与我的问题要点无关,我认为这些问题已在上文中明确、有意、非常笼统地阐述过。如果你不知道答案,那很酷,伙计,不用担心。也就是说,1:gps |导出clixml,2:produate漂亮的HTML表,3:if($u.ws-ge500mb){make_it_red}。但这些只是假设性的例子。@halr9000:你的问题很有争议性(问“最好的方法”…)。在建议的表达式实现之前,标准CSS无法检查文本内容。因此,这是一项用于预处理(XSLT服务器或客户端,任何其他服务器端语言)或后处理(JavaScript)的任务。哪一种最适合您的场景?您需要指定一个标准。然后你需要测试。@skaffman:在标记这个问题之前,我确实投票赞成结束它,然后我也投了反对票。我相信SO的用户不仅可以从好的问题和答案中学习,还可以从坏的问题和答案中学习。SO标记的强大功能很好地支持了这一点。因此,当我们需要向用户展示什么是好问题,什么是坏问题时,我们可以说:看一下
好问题
坏问题
标签中的示例。@Dimitre:我明白你的意思,但这种元标签已经被积极劝阻好几个月了。标签应该反映问题的客观内容,而不是主观意见。@skaffman:好的,那么你认为哪个标签最适合“PL能做到这一点”的问题?当然不是“PL”,但是什么?+1帮助JQuery从银弹演变为银核。但是,当用于HTML电子邮件时,可能不是最好的解决方案,如本文所述。是的,在输出到光盘之前,通过xslt(大致)做同样的事情肯定会更好。。。hmmI删除了对HTML电子邮件的提及——这确实变成了另一个问题。
Add Type-AssemblyName System.Xml.Linq
缺失。切换条件的顺序应该颠倒(或者黄色赢得一切)注意:需要.NET v3.5或v4,下载链接:我还可以从:[System.Environment]开始::CurrentDirectory=拆分路径$MyInvocation.MyCommand。Path@halr9000最好是把$pwd放在储蓄行,我想(修复了)是的,请随意标记我强迫症
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
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
Add-Type -AssemblyName System.Xml.Linq

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

# Find the index of the column you want to format:
$wsIndex = $xml.Descendants("{http://www.w3.org/1999/xhtml}th").
    Where{$_.Value -eq "WS" }.
        NodesBeforeSelf().
            Count

# Format the column based on whatever rules you have:
switch($xml.Descendants("{http://www.w3.org/1999/xhtml}td").Where{@($_.NodesBeforeSelf()).Count -eq $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