R, XPath, text scraping : get the text inside a node, while filtering on the attribute value of one of its descendant

Viewed 38

Here is a quick mock-code. What I want to get is a character vector, with the text content of each p-node for whom the descendant a has its attribute href = "value1".

<doc>
    <div class="intervention">
        <p>
            <a></a>
            <b>
                <a href="value1">xxx</a>
            </b>
            text1
        </p>
        <p>
            <a></a>
            <b>
                <a href="value2">xxx</a>
            </b>
            text2
        </p>
        <p>
            <a></a>
            <b>
                <a href="value1">xxx</a>
            </b>
            text3
        </p>
    </div>

    <div class="intervention">
        <p>
            <a></a>
            <b>
                <a href="value2">xxx</a>
            </b>
            text4
        </p>
        <p>
            <a></a>
            <b>
                <a href="value1">xxx</a>
            </b>
            text5
        </p>
        <p>
            <a></a>
            <b>
                <a href="value1">xxx</a>
            </b>
            text6
        </p>
    </div>
</doc>

In other words, I want to get this vector:

c("xxxtext1","xxxtext3","xxxtext5","xxxtext6")

Could you please help me find the adequate XPath? So far, I have found this one that gives me all the text content in the p node, but I cannot get it to filter based on a's href value.

"//div[@class='intervention']//*[not(self::script)]"

Many thanks in advance for your help!

1 Answers

Your xpath should be //a[@href='value1']/ancestor::p

So for example:

library(xml2)

result <- xml_text(xml_find_all(doc, xpath = "//a[@href='value1']/ancestor::p"))

gsub("\\s", "", result) # Remove line breaks and spaces
#> [1] "xxxtext1" "xxxtext3" "xxxtext5" "xxxtext6"
Related