Valeriane
Valeriane

Reputation: 954

Select xml element matching attribute

I have following xml content :

<root>
    <content>
        <figure id="fig-001">
            <graphic id="fig-001-graId-001"/>
            <graphic id="fig-001-graId-002"/>
            <graphic id="fig-001-graId-003"/>
        </figure>
        <figure id="fig-002">
            <graphic id="fig-002-graId-001"/>
            <graphic id="fig-002-graId-002"/>
        </figure>        
        <refs>
            <ref ref-id="fig-001-graId-001" type="test"/>
            <ref ref-id="fig-002-graId-001" type="test"/>
        </refs>
    </content>
</root>

I use oXygen

I click on an element refs/ref, for example on

<ref ref-id="fig-01-graId-001 type="test" />

I want an xpath which count 'graphic' element in figure having graphic/@id=ref/@ref-id (whene i clicked), something like that :

count(//content/figure/graphic[@id=//ref/@ref-id]/parent::/graphic) ==> 3 (parent of graphic with ref-id=fig-001-graId-001 have 3 graphic elements)

Upvotes: 0

Views: 64

Answers (3)

Daniel Haley
Daniel Haley

Reputation: 52888

You specifically mentioned oXygen, so here's one option:

for $refid in @ref-id return count(//figure[graphic/@id = $refid]/graphic)

This XPath 2.0 would need to be used in the XPath Toolbar (be sure you have XPath 2.0 selected). I don't think you can use the XPath builder because you lose your context.

The only time I could get this to work correctly 100% of the time is to make sure when I clicked on the ref element, the 2 brackets under the start and end of the element were present (after clicking in the XPath Toolbar to run the XPath). This ensures that the context is correct. (This can be done by clicking directly after <ref.)

The brackets are highlighted in the screenshot below. Also notice the correct results at the bottom of the screenshot:

enter image description here

Update: Adding ancestor-or-self::*[1] seems to help with getting the correct context no matter where in the element you click:

for $refid in ancestor-or-self::*[1]/@ref-id return count(//figure[graphic/@id = $refid]/graphic)

Upvotes: 1

michael.hor257k
michael.hor257k

Reputation: 117100

I think you want to do:

count(//graphic[@id=//ref/@ref-id]/../graphic)

Or, if you prefer:

count(//figure[graphic/@id=//ref/@ref-id]/graphic)

Upvotes: 0

Martin Honnen
Martin Honnen

Reputation: 167716

With a key you can use

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:key name="id" match="figure" use="graphic/@id"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
        <xsl:value-of select="count(key('id', //ref/@ref-id)/graphic)"/>
    </xsl:template>
</xsl:transform>

see http://xsltransform.net/ej9EGc1

Upvotes: 0

Related Questions