# How to Use OfficeCLI `query` with CSS‑Like Selectors and Boolean Logic

> Master OfficeCLI query with CSS-like selectors and boolean logic. Filter Office documents dynamically using space separated AND or comma separated OR predicates for powerful data manipulation.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: how-to-guide
- Published: 2026-07-27

---

**Use the `officecli query` command with CSS‑style selectors (e.g., `row[Score>80]`) and combine predicates with implicit AND (space‑separated inside brackets) or explicit OR (comma‑separated selectors) to filter Office documents programmatically.**

The **OfficeCLI** query engine treats Word, Excel, and PowerPoint files as searchable DOM structures, allowing you to extract specific elements using a selector syntax similar to CSS. According to the iOfficeAI/OfficeCLI source code, this capability is implemented across a parser core and document‑specific handlers that translate selectors into OOXML tree traversals.

## How the Query Engine Processes Selectors

When you run `officecli query <file> '<selector>'`, the toolchain routes your request through three architectural layers defined in the repository:

1. **CLI Entry Point** – [`CommandBuilder.GetQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.GetQuery.cs) extracts the raw selector string and dispatches to the appropriate handler based on file extension (`.docx`, `.xlsx`, `.pptx`).
2. **Selector Parsing** – [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs) implements the core `ParseSelector` method, tokenizing the input into element names, attribute predicates, and pseudo‑selectors.
3. **Document Handler Execution** – Format‑specific files like [`WordHandler.Query.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Query.cs), [`ExcelHandler.Query.RowWhere.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ExcelHandler.Query.RowWhere.cs), or [`PowerPointHandler.Query.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.Query.cs) map the parsed tokens to the actual OOXML node tree and return matching elements as JSON.

All selectors are **case‑insensitive** for element and attribute names, and the engine supports **regex‑style matching** via the `~=` operator.

## CSS‑Like Selector Syntax

The selector language supports standard CSS patterns adapted for Office document structures:

- **Element selection** – `paragraph`, `row`, `cell`, `shape`, `slide`, `picture`
- **Attribute predicates** – `[Score>80]`, `[Status="Closed"]`, `[formula~=SUM]`
- **Pseudo‑selectors** – `:contains("text")`, `:empty`, `:no‑alt`
- **Hierarchical combinators** – `>` (direct child), space (descendant)

For example, `slide > shape` matches only shapes that are immediate children of a slide node, while `slide shape` returns shapes at any depth within a slide.

## Boolean Logic: AND, OR, and Composition

The [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs) engine evaluates logical combinations using two primary mechanisms:

### Implicit AND (Space‑Separated Predicates)

Multiple conditions inside a single bracket pair are combined with logical **AND**.

```bash

# Rows where Score > 80 AND Year < 2025

officecli query report.xlsx 'row[Score>80 Year<2025]' --json

```

### Explicit OR (Comma‑Separated Selectors)

Separate selectors with a comma to create a **union** of result sets.

```bash

# All shapes OR pictures (either element type)

officecli query presentation.pptx 'shape, picture' --json

```

### Combined Logic

You can nest AND conditions inside OR groups by repeating the base element:

```bash

# (Score > 80 AND Year < 2025) OR (Status = "Closed")

officecli query data.xlsx 'row[Score>80 Year<2025], row[Status="Closed"]' --json

```

## Practical Query Examples

### Filter by Attribute Value Range

Target cells with numeric thresholds using comparison operators:

```bash

# Cells with value not equal to zero

officecli query sheet.xlsx 'cell[value!=0]' --json

```

### Search Text Content with Pseudo‑Selectors

Use `:contains()` to match text inside elements:

```bash

# Paragraphs containing the word "Revenue"

officecli query contract.docx 'paragraph:contains("Revenue")' --json

# Elements that are empty or contain only whitespace

officecli query notes.docx 'paragraph:empty' --json

```

### Regex Pattern Matching

The `~=` operator enables substring or pattern matching within attributes:

```bash

# Cells whose formula contains "SUM" (case-insensitive)

officecli query budget.xlsx 'cell[formula~=SUM]' --json

```

### Navigate Document Hierarchy

Combine element types with combinators to scope searches:

```bash

# Direct child shapes only (exclude nested groups)

officecli query deck.pptx 'slide > shape' --json

# Any picture anywhere inside a slide (deep search)

officecli query deck.pptx 'slide picture' --json

```

### Complex Boolean Composition

Mix pseudo‑selectors with attribute filters:

```bash

# Cells with a formula that contain "#REF!" errors

officecli query broken.xlsx 'cell[formula]:contains("#REF!")' --json

```

## Working with JSON Output

When you append `--json`, the query returns a structured object you can process with tools like `jq`:

```bash

# Count shapes matching a specific fill color

count=$(officecli query design.pptx 'shape[fill=1E2761]' --json |
        jq '.data.results | length')
echo "Found $count matching shapes"

```

## Summary

- **Entry point** is [`CommandBuilder.GetQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.GetQuery.cs), which routes the selector string to document‑specific handlers.
- **Implicit AND** combines multiple attribute predicates inside single brackets (e.g., `[Score>80 Year<2025]`).
- **Explicit OR** uses commas to union separate selectors (e.g., `shape, picture`).
- **Pseudo‑selectors** like `:contains("text")` and `:empty` filter based on content rather than attributes.
- **Regex matching** uses the `~=` operator within attribute brackets.
- **Hierarchical traversals** use `>` for direct children and spaces for any‑depth descendants.

## Frequently Asked Questions

### How do I perform an OR operation between different attributes?

Use a comma to separate complete selector strings. For example, `row[Score>80], row[Status="Active"]` returns rows where either the score is greater than 80 **or** the status equals Active. To combine attributes with AND, place them inside the same brackets: `row[Score>80 Status="Active"]`.

### Can I use AND and OR together in one query?

Yes. Create multiple selector groups separated by commas, where each group can contain its own AND conditions. For instance, `cell[formula~=SUM value>100], cell[formula~=AVERAGE value<50]` matches cells that either contain a SUM formula with values over 100 **or** contain an AVERAGE formula with values under 50.

### What pseudo‑selectors are supported besides `:contains`?

According to [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs) and the handler implementations, the engine recognizes `:empty` (elements with no content), `:no‑alt` (images lacking alternative text), and `:contains("string")` (text content matching). Availability varies slightly by document type—PowerPoint handlers expose shape‑specific filters, while Excel handlers focus on cell and row predicates.

### Is the query syntax case‑sensitive?

No. The selector engine in [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs) normalizes element names and attribute keys to lowercase during the parsing phase, so `Row[Score>80]` and `row[score>80]` evaluate identically. However, string values inside quotes (e.g., `"Revenue"`) are matched literally against the document content.