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')