在没有完整的Get-Content的情况下提取早期属性值

在PowerShell中,我知道我可以做这样的事情:

[xml]$myxml = Get-Contents .\oneofmyxmlfiles.xml
$myxml.Wrapper.Data.HeaderStuff.SomeHeaderAttribute

并从类似

的位置获取我想要的结果(WhatIWantToExtract
<Wrapper>
    <Data>
        <HeaderStuff SomeHeaderAttribute="WhatIWantToExtract" />
...a bunch of other stuff...
    </Data>
...a bunch of more other stuff...
</Wrapper>

我需要对很多文件进行此操作,这些文件可能很大。但是,HeaderStuff元素唯一,并且总是非常靠近文件顶部

有没有一种方法可以从文件顶部附近直接提取“而不用Get-Content加载整个内容?”

raners 回答:在没有完整的Get-Content的情况下提取早期属性值

您可以使用.NET XmlReader读取XML文件,并在获得所需信息后立即停止进一步处理。

优点:它非常快,几乎没有内存使用。缺点:您必须使用标记来维护您正在阅读的内容的上下文,因为阅读器的工作方式就像在文件中移动光标一样。它仅保持其位置以及当前正在查看的内容。您必须做所有必要的簿记工作。

以下内容返回其遇到的第一个SomeHeaderAttribute元素的<HeaderStuff>属性的值,并在此之后停止处理。适应您的特定XML布局和需求。

using namespace System.IO
using namespace System.Xml

function Get-HeaderStuff {
    param([string]$xmlFilePath)

    try {
        $stream = New-Object FileStream -ArgumentList ($xmlFilePath,[FileMode]::Open)

        $settings = New-Object XmlReaderSettings
        $settings.Async = $false

        $reader = [XmlReader]::Create($stream,$settings)
        while ($reader.Read()) {
            if (
                $reader.NodeType -eq [XmlNodeType]::Element -and 
                $reader.Name -eq "HeaderStuff"
            ) {
                return $reader.GetAttribute("SomeHeaderAttribute")
            }
        }
    } finally {
        # clean up
        if ($reader) { $reader.Dispose() }
        if ($stream) { $stream.Dispose() }
    }
}

您将使用XML文件的路径来调用它:

$result = Get-HeaderStuff ".\oneofmyxmlfiles.xml"
Write-Host $result
,

我将使用TheIncorrigible1建议,“使用Get-Content的TotalCount参数”:

$fivelines = Get-Content .\oneofmyxmlfiles.xml -TotalCount 5

结果是包含五个元素的System.Array。我的XML文件具有非常可预测的结构,因此我可以轻松地隔离出所需的特定行(数组元素),然后使用简单的字符串匹配技术找出我想要的属性值。

感谢Tomalak,您的解决方案似乎更优雅,更强大,但比我目前愿意做的工作还要多。

本文链接:https://www.f2er.com/3165375.html

大家都在问