---
title: "Linguagem de Consulta XPath"
subtitle: "Caminhos, predicados, ancestrais e funções"
bibliography: ../config/refs.bib
csl: ../config/ABNT-UFPR-2011-Mendeley.csl
output:
  beamer_presentation:
    # keep_md: true
    keep_tex: true
---

```{r, include = FALSE}
source("../config/setup.R")
```

## Introdução

### Motivação

  * **XPath** é uma linguagem de consulta para XML.
  * Ela é baseada em notação de caminhos e é bastante flexível.
  * Com XPath pode-se:
    * Utilizar regras lógicas em atributos e conteúdo.
    * Descrever caminhos baseados em relação vertical e horizontal.
    * Aplicar funções numéricas e de texto.
  * Existem outras formas de apontar para extração mas geralmente são
    subótimas comparadas ao XPath.

## Introdução

### Objetivos

  * Introduzir o básico da sintaxe XPath para consultas.
  * Apresentar uso dos predicado e genealogia em consultas XPath.
  * Ilustrar o uso de predicados, operadores e funções.

# XPath

## Características

  * É uma **linguagem de consulta** para endereçamento e extração de
    informação em documentos XML/HTML.
  * É um padrão do *World Wide Web Consortium* (W3C).
  * Só funciona com a representação DOM do documento e descreve
    caminhos pelos nós e ramos da árvore.
  * Uma instrução XPath retorna o conteúdo que bate com o caminho
    descrito.
  * Em alguns aspectos, se assemelha a Expressões Regulares.

## Documentação do XPath no W3C

### Documentação

  1. XPath está na versão 3.1.
  2. Documentação para cada versão: <https://www.w3.org/TR/xpath/all/>.
  3. De acordo com o [código fonte](https://github.com/GNOME/libxml2/blob/master/xpath.c),
     a `libxml2` usa o XPath 1.0.

### Tutoriais

  3. <https://www.w3schools.com/xml/xpath_intro.asp>.
  2. <https://docs.marklogic.com/guide/xquery/xpath>;
  1. <https://www.tutorialspoint.com/xpath/>.
  4. <http://www.utools.nl/downloads/XPathReference.pdf>.

## Cartões de referência e testadores online

### Cartões de referência

  1. <http://ricostacruz.com/cheatsheets/xpath.html>.
  3. <http://xpath.alephzarro.com/content/cheatsheet.html>.
  4. <http://www.mulberrytech.com/quickref/XSLT_1quickref-v2.pdf>.

### Testadores online de XPath

  1. <http://xpather.com/>.
  2. <http://codebeautify.org/Xpath-Tester>.
  3. <http://www.webtoolkitonline.com/xml-xpath-tester.html>.
  4. <http://www.freeformatter.com/xpath-tester.html>.

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Seleção de descentes. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/01-descendant-selectors.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Significado dos prefixos. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/02-prefixes.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Combinação de seleção e prefixos. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/03-steps-and-axes.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Seleção de filhos. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/04-child-axes.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Seleção de descendentes. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/06-descendant-or-self-axes.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Diferentes formas de caminho vertical e horizontal. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/05-using-axes.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Seleção de irmãos ou caminhos horizontais. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/08-siblings.png")
```

---

```{r, echo = FALSE, out.width = "6.5cm", fig.cap = cap}
cap <- "Outras especificações de eixos verticais e horizontais. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/07-other-axes.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Seleção baseada nos atributos. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/09-attributes-selectors.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Seleção pela posição. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/10-indexing.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Mais seleção por posição. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/11-order-selectors.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Uso de predicados nos nós. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/12-predicates.png")
```

---

```{r, echo = FALSE, out.width = "10cm"}
knitr::include_graphics("./img/13-operators.png")
asis_output("\\vspace{-0.75cm}")
```

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
knitr::include_graphics("./img/14-boolean-functions.png")
cap <- "Operadores de comparação e lógicos. Fonte: \\url{https://devhints.io/xpath}."
```

---

```{r, echo = FALSE, out.width = "10cm"}
knitr::include_graphics("./img/13-unions.png")
asis_output("\\vspace{-0.75cm}")
```

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "União de expressões e encadeamento. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/15-nesting-predicates.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Funções aplicáveis aos nós. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/16-node-functions.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Funções de texto aplicáveis aos nós. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/17-string-functions.png")
```

---

```{r, echo = FALSE, out.width = "10cm", fig.cap = cap}
cap <- "Combinando funções e precedência de seleção. Fonte: \\url{https://devhints.io/xpath}."
knitr::include_graphics("./img/18-using-nodes.png")
```

## Exemplos de uso do XPath

Usar esse conteúdo no <http://xpather.com/> para avaliar expressões
XPath.

```
<body>
  <div type="orçamento">
    <p>
      Essa sobremesa custa <span class="valor">10 reais</span>
      e serve <span class="quantidade">6 pessoas</span>.
    </p>
  </div>
  <div type="sobremesa">
    <ul class="ingredientes">
      <li>3 ovos.</li>
      <li>150 ml de leite.</li>
      <li>3 colheres de manteiga.</li>
      <li>Massa preparada de bolo.</li>
    </ul>
    <ul class="preparo">
      <li>Deixe o forno preaquecer por 20 min a 180 graus.</li>
      <li>Bata os ingredientes até uniformizar.</li>
      <li>Unte a forma.</li>
      <li>Despeje na forma.</li>
      <li>Leve ao fogo por aproximadamente 1 hora.</li>
    </ul>
  </div>
</body>
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //span
knitr::include_graphics("./img/crop-XPath243.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
## //ul[@class = 'ingredientes']/li
knitr::include_graphics("./img/crop-XPath265.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
## //ul[last()]/li[position() < last() - 2]
knitr::include_graphics("./img/crop-XPath248.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //ul/li[position() > 1 and position() < last()]
knitr::include_graphics("./img/crop-XPath266.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //ul[count(./li) = 4]
knitr::include_graphics("./img/crop-XPath262.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //*[@class and not(./li)]
knitr::include_graphics("./img/crop-XPath252.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //li[starts-with(text(), 'D')]
knitr::include_graphics("./img/crop-XPath250.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //p/parent::div
knitr::include_graphics("./img/crop-XPath258.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //div[./p]
knitr::include_graphics("./img/crop-XPath259.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //p/ancestor::div
knitr::include_graphics("./img/crop-XPath254.png")
```

---

```{r, echo = FALSE, out.width = "8.5cm"}
# //span[contains(., 'reais') or contains(., 'pessoas')]
knitr::include_graphics("./img/crop-XPath264.png")
```

## Resumo de recursos do XPath

  * Prefixos e eixos:
    * `./`, `/`, `//`.
    * Verticais: `child::`, `parent::`, `descendant::`, `ancestor::`,
      etc.
    * Horizontais: `following-sibling::`, `preceding-sibling::`.
  * Metacacteres: `.`, `..`, `@`, `*`.
  * Predicados: `[···]`.
  * Operadores de comparação: `=`, `!=`, `<`, `<=`, `>`, `>=`.
  * Operadores lógicos: `and`, `or`, `not()` e `|`.
  * Funções: `text()`, `name()`.
  * Funções numéricas: `count()`, `position()`, `last()`, etc.
  * Funções de texto: `contains()`, `starts-with()`, etc.

## Resumo

  * XPath é uma linguagem **flexível e poderosa** para consultar XML/HTML.
  * HTML são profundos na hierarquia e requerem uso de predicados para
    **delimitar a consulta**.
  * O domínio dos recursos do XPath são fundamentais para especificar
    buscas precisas, fáceis de criar e manter.
  * O emprego de predicados, eixos e funções potencializa a aplicação do
    XPath.
  * O mesmo resultado pode ser conseguido com diversas expressões.
  * Os predicados podem ser combinados de várias formas.
  * Como expressões regulares, e necessário equilibrar
    **especificidade** e **generalidade** para reduzir manutenção do
    código.
