Use Xpath to search for the value of a fieldname and print another attribute if the statement is true

落爺英雄遲暮 提交于 2020-03-26 03:51:33

问题


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()]
  • //Field find 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!