Home > Software engineering >  Filtering elements from a complex XML document
Filtering elements from a complex XML document

Time:10-10

I have this XML - the objective is to filter certain properties from the XML given some conditions: so, get the SALARY of a player whose NAME is ALONSO and POSITION is a STRIKER

<PLAYERS>
  <PLAYER>
    <NAME>ALONSO</NAME>
    <POSITION>MIDFIELDER</POSITION>
    <AGE>28</AGE>
    <NATIONALITY></NATIONALITY>
    <SALARY>550000</SALARY>
  </PLAYER>
  <PLAYER>
    <NAME>MANE</NAME>
    <POSITION>STRIKER</POSITION>
    <AGE>30</AGE>
    <NATIONALITY></NATIONALITY>
    <SALARY>600000</SALARY>
  </PLAYER>
  <PLAYER>
    <NAME>ALONSO</NAME>
    <POSITION>STRIKER</POSITION>
    <AGE>23</AGE>
    <NATIONALITY>SPAIN</NATIONALITY>
    <SALARY>250000</SALARY>
  </PLAYER>
</PLAYERS>

This is what I tried -

val salary = ("PLAYERS").flatMap {
      case pNode if (pNode \\ "PLAYER" \\ "NAME").head.text == "ALONSO" =>
        (pNode \\ "PLAYER" \\ "SALARY").headOption.map(_.text)
      case _ => None
    }.headOption
 
 // result   
 salary

This seems to return the first salary in the XML - which isn't what I require! Any assistance will be highly appreciated!

CodePudding user response:

Since you tagged your question as xslt, here's an XSLT answer:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/PLAYERS">
    <xsl:value-of select="PLAYER[NAME='ALONSO' and POSITION='STRIKER']/SALARY"/>
</xsl:template>

</xsl:stylesheet>

CodePudding user response:

In the current code, you are checking whether the first node of an Elem contains "ALONSO". So if you change the order and make the first player's name "Rooney", for eg, you will get an empty list.

Instead, you could try,

players.child.flatMap {
  case pNode if (pNode \\ "PLAYER" \\ "NAME").text == "ALONSO" =>
    (pNode \\ "PLAYER" \\ "SALARY").headOption.map(_.text)
  case _ => None
}
  • Related