Home > Enterprise >  XML/Xpath 1.0: Checking if any descendant of a given node contains a specific attribute value?
XML/Xpath 1.0: Checking if any descendant of a given node contains a specific attribute value?

Time:10-28

I am working with a content management system that allows placing elements depending on XPath rules. Here is a simplified example:

<...>
  <chapter>
    <node2>
      <step tool="pencil"></img>
    </node2>
    <node3>
      <node4>
        <step tool="screwdriver"></img>
      </node4>
    </node3>
  </chapter>
</...>

I'm trying to place a toolbox at the beginning of the chapter. This toolbox shall contain all the tools someone will need for the described process, e.g. a pencil and a screwdriver. To do so, I'm placing all possible tool-icons in the toolbox and hide/show the icons that are needed with a rule.

This rule is my problem. The structure of a chapter may vary. Example: For the pencil, I need to know if any @tool below my current chapter has the value "pencil". The structure inside may and will vary. However, only can contain a @tool.

What I did so far:

boolean(descendant::step[1]/@tool = 'pencil')

That works for the given example. But of course it starts to fail as soon as 'pencil' is no longer the value of the first @tool. This will happen if anyone changes the file.

I've read about wildcards, but

boolean(descendant::step[*]/@tool = 'pencil')

returns false, e.g. pencil icon stays hidden. As far as I understood, this should have selected every that's a descendant of my current node and check if it has an attribute @tool with the value 'pencil'.

How can I do this?

CodePudding user response:

If you don't care about the position, then remove the predicate specifying the first one.

Any descendant step element that has @tool of pencil:

boolean(descendant::step/@tool = 'pencil')

Any descendant element * that has @tool of pencil:

boolean(descendant::*/@tool = 'pencil')
  • Related