我有一个包含;
的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>
我需要找到带有值=&#34; 27606_ManufacturingProcess8&#34;的ManufacturingProcessID属性,如果我找到它,那么查看同一节点下的ProcessStatusID属性,如果值=&#34; psClosed&# 34;然后我需要将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
}
}
}
}
}
答案 0 :(得分:1)
您应该寻找父节点并深入挖掘它。不确定您的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>
然后代码将识别是否有任何'Object'节点具有名称为“ManufacturingProcessID”的Property元素设置为Value“27606_ManufacturingProcess8”,而在同一节点中,名称为“ProcessStatusID”的属性设置为Value“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 ....}
希望它有所帮助!
答案 1 :(得分:1)
by generating and executing INSERT statements在 Select-Xml
的正确轨道上,它支持XPath查询,但不是仅使用query {提取更高级别的<Object>
元素{1}}以后 - 在管道中进行慢速处理,您可以使用单个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..."
}
如何直接从Select-Xml
接受文件输入
只会为XPath查询返回匹配项的输入文件输入Get-ChildItem
脚本块。