Search code examples
xmldatabasexpathdtd

why my xpath query doesn't work?


my DTD and XML:

<!DOCTYPE test [
  <!ELEMENT team(owner+)>
  <!ATTLIST team
    name ID #REQUIRED
    coach IDREF #REQUIRED
    >
  <!ELEMENT owner      (#PCDATA)>
  <!ELEMENT coach    EMPTY>
  <!ATTLIST coach
    name ID #REQUIRED
    >
  <!ELEMENT game    EMPTY>
  <!ATTLIST game
    teams IDREFS #REQUIRED
    winner IDREF #REQUIRED
    >
  <!ELEMENT db    (coach*,team*,match*)>
]>


<?xml version="1.0" ?> 

    <db>
        <team name = "Hapoel" coach = "Abuksis">
            <owner> Eli Tabib</owner>
        </team>
        <team name = "Maccabi" coach = "Blat">
            <owner> Shimi</owner>
            <owner> Federman</owner>
        </team>
        <team name = "Beitar" coach = "Eli Cohen">
            <owner> Arkadi</owner>
        </team>
        <team name = "ElitzorLavi" coach = "Eli">
            <owner> Zehava</owner>
            <owner> Dani</owner>
        </team>
        <coach name = "Abuksis"/>
        <coach name = "Eli Cohen"/>
        <coach name = "Blat"/>
        <coach name = "Eli"/>
        <game teams = "Hapoel" winner = "Maccabi"/>
        <game teams = "Hapoel Beitar" winner = "Beitar"/>
        <game teams = "Maccabi ElitzorLavi" winner = "Maccabi"/>
        <game teams = "Elitzor Lavi Maccabi" winner = "Maccabi"/>
    </db>

i have to find the games such that number of teams is <2 now I expect to get only the first game. i tries this Xpath: db/game[count(/@teams)<2] but it gives me all games.. what is my mistake?


Solution

  • The expression @teams denotes the attribute named teams. The expression count(@teams) counts the number of attributes with that name; naturally it evaluates to 1 for each game in your input, because each game in your input has exactly one attribute named teams.

    If you want to count the number of tokens in the value of the attribute named teams, your mistake is counting occurrences of the attribute instead of counting what you want to count. You'll need to find a way to tokenize the value of the attribute and then count tokens, or another way to express the condition you need to test. (Hint: after whitespace normalization a value with a single token will contain no blanks. A value with multiple tokens will.)

    And heed Marc B's advice.