问题
I'm currently searching for a way to search a xml-file and display a attribute if a condition is satisfied.
The xml-file goes like that
<Import xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Category Name="Personen-Stellen-Import">
<Record>
<Field FieldName="Person.EmailGeschaeft">
<String>bla.blup1@ospelt.com</String>
</Field>
<Field FieldName="Person.IstReferent">
<String>1</String>
</Field>
</Record>
<Record>
<Field FieldName="Person.EmailGeschaeft">
<String>bla.blup2@ospelt.com</String>
</Field>
<Field FieldName="Person.IstReferent">
<String>0</String>
</Field>
</Record>
<Record>
<Field FieldName="Person.EmailGeschaeft">
<String>bla.blup3@ospelt.com</String>
</Field>
<Field FieldName="Person.IstReferent">
<String>0</String>
</Field>
</Record>
<Record>
<Field FieldName="Person.EmailGeschaeft">
<String>bla.blup4@ospelt.com</String>
</Field>
<Field FieldName="Person.IstReferent">
<String>1</String>
</Field>
</Record>
</Category>
</Import>
Every person has its entries between <rekord> and </rekord>. Now if the string under the Field Fieldname = "Person.IstReferent" matches 1, it should print the E-Mail of this specific Person.
The E-Mail is stored in a string below the FieldName"Person.EmailGeschaeft. Do you know any way to make a powershell-script, which can display all the E-Mails which match the condition and print it in a file or display it?
回答1:
It is definitely possible.
First, you need to load your XML file and cast it as a XML using [xml]$xml = Get-Content -Path 'YourXml.xml' -Raw
Then, to get the emails corresponding to what you want, you can use the following statement.
Here's what is needed to accomplish exactly that.
[xml]$xml = Get-Content -Path 'YourXml.xml' -Raw
$MatchingNodes= Select-xml -Xml $xml -XPath '//*[Field[@FieldName="Person.IstReferent"]/String[text() =1]]/Field[@FieldName="Person.EmailGeschaeft"]/String[text()]'
$Emails = $MatchingNodes.Node.'#text'
You will obtain the following result.
bla.blup1@ospelt.com
bla.blup4@ospelt.com
The XPATH syntax used can be decomposed in the following way.
//*[Field[@FieldName="Person.IstReferent"]/String[text() =1]]/Field[@FieldName="Person.EmailGeschaeft"]/String[text()]
//Fieldfind all Field tags//*[Find whatever is inside the brackets but gives back the nodes at that level rather than giving the child.Field[@FieldName="Person.IstReferent"The FieldName attribue with a value of Person.IstReferent as a child of the Field node./String[text()=1]The String node should have a value of 1
Then, if you combine that first part, you get
//*[Field[@FieldName="Person.IstReferent"]/String[text() =1]]
Which means: "Find the node matching that specific condition but Give me the node at the Field level instead of the 1 value (That,s why you have the *[ so you return to that level. From that matching Record node, we navigate to what we actually want.
/Field[@FieldName="Person.EmailGeschaeft"]/String[text()]
- The Field node which contains a FieldName attribute matching Person.EmailGeschaeft that have a child node called String
[Text()]is the syntax here to say that we want the value of that node.
Reference
Select-xml
回答2:
Sage Pourpre's answer is perfect. Shorter XPath :
//String[text()="1"]/preceding::String[1]/text()
来源:https://stackoverflow.com/questions/59893282/use-xpath-to-search-for-the-value-of-a-fieldname-and-print-another-attribute-if