2012-08-14 73 views
1

我正在處理與以下內容類似的xml文件。但是,它是以下幾千倍。我將使用powershell通過xml解析解析XML並查找字符串的所有實例

我需要找到字符串「c:\」出現的所有任務的任務名稱。雖然這可能很容易,如果只有一個字符串可能顯示區域,它可以完全顯示在整個任務。在這個特定的任務中,我把C:\放在4個不同的時間。

,我希望能得到任務名稱的輸出,以及給定的路徑被引用的地方......

<Task ID="00000000" Name="Task name goes here" Active="0" NextEID="22" CacheNames="random" AR="0" TT="COS"> 
     <Info> 
      <Description> 
      </Description> 
      <Notes> 
      </Notes> 
     </Info> 
     <Parameters> 
      <moreParameters>C:\pathGoesHere</moreParameters> 
     </Parameters> 
     <Schedules/> 
     <Source HostID="0" Type="FileSystem" Path="C:\path" FileMask="[Parm:parameter].txt" DeleteOrig="0" NewFilesOnly="0" SearchSubdirs="0" Unzip="0" RetryIfNoFiles="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefRescanSecs="1" UDMxFi="1" UDMxBy="1" ID="11"/> 
     <For ID="13"> 
      <Destination HostID="000000" Type="siLock" FolderID="" FolderType="4" FolderName="Home/[Parm:parameter]/" Subject="" FileName="[OnlyName]_[YYYY][MM][DD].bai" UseOrigName="0" ForceDir="1" OverwriteOrig="1" UseRelativeSubdirs="1" Zip="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefUser="1" UseDefClientCert="1" ID="12"/> 
      <If ID="14"> 
       <When> 
        <Criteria> 
         <comp a="[ErrorCodeFile]" test="NEQ" b="0"/> 
        </Criteria> 
        <UpdOrig Action="d" ID="15"/> 
        <Destination HostID="0000000000" Type="Share" Path="C:\anotherCPath" FileName="[Parm:parameter]_[YYYY][MM][DD].bai" UseOrigName="0" ForceDir="1" OverwriteOrig="1" UseRelativeSubdirs="1" Zip="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" ID="17"/> 
       </When> 
      </If> 
     </For> 
     <If ID="19"> 
      <When> 
       <Criteria> 
        <comp a="[ErrorCodeTask]" test="NNE" b="0"/> 
       </Criteria> 
       <Email HostID="385322183" Subject="[TaskStatus]-[TaskName]" Message="" AddressTo="[email protected]" Attachment = "C:\path\" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" ID="20"/> 
      </When> 
     </If> 
    </Task> 
+0

您正在使用哪種語言? – Dave 2012-08-14 16:49:38

+0

powershell。對不起 – mhopkins321 2012-08-14 16:50:14

回答

6

假設XML位於file.xml,以下XPath與回報你Name屬性: 字符串 「C:\」 可能是在:

//Task[contains(text(), "C:\") or //*[contains(text(), "C:\")] or //*[@*[contains(., "C:\")]]]/@Name 

說明:

    文本 Task標籤
  • 文本任何兒童
  • 在任何兒童的任何屬性

PowerShell的樣本:

#read xml 
$xml = [xml](gc -Encoding utf8 .\test.xml) 

#process it 
$xml | 
    Select-Xml '//Task[contains(text(), "C:\") or //*[contains(text(), "C:\")] or //*[@*[contains(., "C:\")]]]/@Name' | 
    % { $_.Node."#text" } 
+0

我希望我能給你100個綠色的複選標記! – mhopkins321 2012-08-14 17:52:00

+0

我剛纔看到這個答案產生了超過1400條記錄的文本文件,因此節省了我幾個小時的手工工作。看起來像我可以採取休息一週休息:-P – mhopkins321 2012-08-14 17:57:35

+0

thx,如果你熟悉Xpath,你可以做更多 – Akim 2012-08-15 04:37:34

1

當你施放到[XML],您可以訪問一切都使用非常好的「屬性」語法。具有相同標籤的多個節點將作爲數組公開。然後,您可以使用InnerXml屬性獲取定義當前節點的原始XML字符串。然後您只需要對您的搜索字符串進行簡單的「類似」匹配。

假設你有下一個「任務」節點的多個「任務」節點在一個文件中:

$tasks = [xml] (Get-Content .\Tasks.xml) 
$tasks.Tasks.Task |?{ $_.InnerXml -like '*C:\*' } | select -expand Name 

或者,如果在每個多個文件的單個任務節點:

dir *.xml |%{ [xml] (Get-Content $_) } |?{ $_.Task.InnerXml -like '*C:\*' } | select -expand Name 

這些將爲您提供任務名稱。獲取包含搜索字符串的節點中的每一行都有點棘手。這是一個黑客正則表達式的方法(我知道我知道,不要用正則表達式解析XML ...)。同樣,假設每個XML文件中有一個Task節點:

$taskXmls = dir *.xml |%{ [xml](Get-Content $_) } 

foreach($taskXml in $taskXmls) 
{ 
    if($taskXml.Task.InnerXml -like '*C:\*') 
    { 
     $hits = [Regex]::Matches($taskXml.Task.InnerXml, '<[^<]*C:\\[^>]*>') 
     $hitList = $null 
     if($hits) 
     { 
      $hitList = $hits | select -expand Value 
     } 
     new-object psobject -prop @{TaskName = $taskXml.Task.Name; Hits = $hitList} 
    } 
}