我有一个XML文件,其中包含;
<?xml version="1.0"?>
<JobContainer version="2017-1">
<Object name="MainObject" type="TDM_Container">
<Object name="OrderList" type="TDM_List_Order">
<List name="Items">
<Object type="TDM_Item_Order">
<Property name="IntOrderID" value="3I-390049-SZEPLOUSKI-793269"/>
</Object>
</List>
</Object>
<Object name="ModelJobList" type="TDM_List_ModelJob">
<List name="Items">
<Object type="TDM_Item_ModelJob">
<Property name="ModelJobID" value="MJ5393C2FF84844DE38BC481CB5AD36D93"/>
</Object>
</List>
</Object>
<Object type="TDM_Item_ModelElement">
<Property name="ModelJobID" value="MJ5393C2FF84844DE38BC481CB5AD36D93"/>
<Property name="ProcessStatusID" value="psScanned"/>
<Property name="ProcessLockID" value="plReady"/>
<Property name="ManufacturingProcessID" value="57435_ManufacturingProcess17"/>
<Property name="ManufacturerID" value="27606"/>
</Object>
<Object type="TDM_Item_ModelElement">
<Property name="ModelJobID" value="MJ5393C2FF84844DE38BC481CB5AD36D93"/>
<Property name="ProcessStatusID" value="psClosed"/>
<Property name="ProcessLockID" value="plReady"/>
<Property name="ManufacturingProcessID" value="27606_ManufacturingProcess8"/>
<Property name="ManufacturerID" value="27606"/>
</Object>
<Object type="TDM_Item_ModelElement">
<Property name="ModelJobID" value="MJ5393C2FF84844DE38BC481CB5AD36D93"/>
<Property name="ProcessStatusID" value="psScanned"/>
<Property name="ProcessLockID" value="plReady"/>
<Property name="ManufacturingProcessID" value="57435_ManufacturingProcess17"/>
<Property name="ManufacturerID" value="27606"/>
</Object>
</List>
</Object>
<Object name="ElementList" type="TDM_List_Element">
<List name="Items">
<Object type="TDM_Item_Element">
<Property name="Anatomical" value="False"/>
</Object>
</List>
</Object>
</Object>
</JobContainer>
我需要找到带有value =“27606_ManufacturingProcess8”的ManufacturingProcessID属性,如果我找到它然后查看同一节点下的ProcessStatusID属性,如果值=“psClosed”,那么我需要将xml文件移动到另一个文件夹。
我的代码在下面工作,但它只在节点是第一个时才起作用。但有时节点不是第一个节点。如果该节点不是第一个节点,我该如何找到它。
Get-ChildItem $sSourceFolder | ForEach-Object -Process {
if ($_.PSIsContainer)
{
# Store subfolder path in a variable
$sFolderPath = $_.FullName
$sFolderName = Split-Path $sFolderPath -Leaf
Get-ChildItem $sFolderPath | Where {$_.Name -like $sFolderName + '.xml'} | foreach{
$sFilepath = $_.FullName
[xml]$xml2 = Get-Content $sFilepath
$sValueMPI = $xml2.SelectNodes('//Property') | ?{$_.name -eq "ManufacturingProcessID"} | select -First 1 -ExpandProperty value
if ($sValueMPI -eq '27606_ManufacturingProcess8')
{
$sValue = $xml2.SelectNodes('//Property') | ?{$_.name -eq "ProcessStatusID"} | select -First 1 -ExpandProperty value
if ($sValue -eq 'psClosed')
{
# If destination folder already exists, add sequential suffix like (1), (2), etc.
if (Test-Path ($sDestFolder + $sFolderName))
{
$j = 1
While (Test-Path ($sDestFolder + "$sFolderName($j)"))
{
$j = $j + 1
}
$sFolderName = "$sFolderName($j)"
}
# Move folder to archive destination
Move-Item $sFolderPath ($sDestFolder + $sFolderName) -ErrorVariable MoveError -Verbose -Force *>> $sLogPath
if (!($MoveError)) {$i = $i + 1} #if no move error, then increment counter
}
}
}
}
}
你应该寻找父节点并深入研究它。不确定您的XML文件的外观,因为您没有发布上面的有效代码。但是,请说它看起来像下面的那个
<Object type="TDM_Item_ModelElement">
<Property name="ModelElementID" value="MEC35A1D182F984AE893952151DA417D51"/>
<Property name="ModelJobID" value="MJ5393C2FF84844DE38BC481CB5AD36D93"/>
<Property name="MaterialID" value="26167_Ti (xyz)"/>
<Property name="ColorID" value=""/>
<Property name="ProcessStatusID" value="psClosed"/>
<Property name="AltProcessStatusID" value="psClosed"/>
<Property name="ProcessLockID" value="plReady"/>
<Property name="ManufacturingProcessID" value="27606_ManufacturingProcess8"/>
<Property name="ManufacturerID" value="27606"/>
</Object>
然后代码将识别是否存在具有名称“ManufacturingProcessID”的Property元素设置为值“27606_ManufacturingProcess8”的任何“Object”节点,而在同一节点中,名称“ProcessStatusID”设置为值“psClosed”的属性如下。把它写成一个单行,所以它读起来有点乱,但它的作用是通过$ xml2内容查找父元素“Object”,其中所有“Property”元素都是嵌套的,然后它检查属性是否与上述名称具有所需的值。如果找到至少一个节点,那么你点击了你想要存档的XML文件或者什么;)
$validNodes = $xml2 | Select-Xml -XPath '//Object' | %{$_ | ?{((($_.Node.Property.Name -eq "ManufacturingProcessID") -and ($_.Node.Property.Value -eq "27606_ManufacturingProcess8")) -and (($_.Node.Property.Name -eq "ProcessStatusID") -and ($_.Node.Property.Value -eq "psClosed")))}}
if ($validNodes.Count -gt 0) { ... Do your file operation ....}
希望能帮助到你!
Stanislav Castek's answer与Select-Xml
在正确的轨道上,<Object>
支持XPath查询,但是不是仅使用查询//Object
提取更高级别的# Formulate the XPath query
$xpathQuery = '//Property[@value="{0}"]/../Property[@value="{1}"]' -f
'27606_ManufacturingProcess8', 'psClosed'
# ...
Get-ChildItem -File $sFolderPath -Filter ($sFolderName + '.xml') |
Select-Xml $xPathQuery | ForEach-Object {
$file = $_.Path # full path of the input file
# Perform the move...
Write-Verbose -Verbose "Moving $file..."
}
元素 - 稍后 - 在管道中进行慢速处理,您可以使用单个XPath表达式执行整个查询:
Select-Xml
请注意Get-ChildItem
如何直接从ForEach-Object
接受文件输入。
仅为XPath查询返回匹配的输入文件输入qazxswpoi脚本块。