# How to Use CSS-Like Selectors and Boolean Operators in the OfficeCLI Query Command

> Master OfficeCLI query with CSS selectors and boolean operators. Learn to search documents efficiently using AND and OR logic with this powerful command. Enhance your OfficeCLI skills today.

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

---

**The `officecli query` command searches Office documents using CSS-inspired selectors where multiple attribute predicates inside brackets imply logical AND, while comma-separated selectors create logical OR unions.**

The OfficeCLI tool by iOfficeAI provides a command-line interface for programmatically inspecting Word, Excel, and PowerPoint files. The `query` verb implements a domain-specific selector engine that parses CSS-like syntax to target specific OOXML elements, supporting complex boolean logic for precise document mining without custom scripts.

## How the Query Engine Works

The selector engine processes queries through a pipeline defined in three core layers. In [`src/officecli/CommandBuilder.GetQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/CommandBuilder.GetQuery.cs), the CLI entry point extracts the raw selector string and routes it to the appropriate document handler based on file extension. The [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs) file contains the core parser that tokenizes selectors into **element names**, **attribute predicates**, and **pseudo-selectors**, then evaluates them against the OOXML DOM. Format-specific implementations in [`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), and [`PowerPointHandler.Query.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.Query.cs) map these generic selectors to concrete WordprocessingML, SpreadsheetML, and PresentationML nodes.

## CSS-Like Selector Syntax

OfficeCLI supports standard CSS selector patterns adapted for Office document structures.

**Element Selectors** match OOXML node names case-insensitively (e.g., `row`, `cell`, `paragraph`, `shape`, `slide`).

**Attribute Predicates** use bracket notation with comparison operators:
- `attr=value` – exact equality
- `attr!=value` – inequality
- `attr>num` / `attr<num` – numeric comparison
- `attr~=pattern` – regex-style substring match

**Pseudo-Selectors** filter by content state:
- `:contains("text")` – elements containing specific text
- `:empty` – elements with no content or whitespace only
- `:no-alt` – elements lacking alternative text attributes

## Boolean Operators and Combinators

The engine implements boolean logic through specific syntactic conventions rather than explicit keywords.

**Implicit AND** occurs when multiple predicates appear within the same brackets. The parser requires all conditions to match for the element to qualify.

```bash

# Rows where Score > 80 AND Year < 2025

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

```

**Explicit OR** uses the comma (`,`) to create a union of result sets, similar to CSS group selectors.

```bash

# All shapes OR pictures (union of both sets)

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

```

**Hierarchy Combinators** define structural relationships:
- **Space** (`slide shape`) – descendant combinator matching any nested depth
- **Greater-than** (`slide > shape`) – child combinator matching only direct children

## Practical Code Examples

Below are executable patterns demonstrating boolean composition across different Office formats.

### Combining AND with OR

Mix implicit conjunction and comma-separated unions to express complex logic:

```bash

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

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

```

### Content-Based Filtering with Pseudo-Selectors

Target elements by their text content or emptiness:

```bash

# Paragraphs containing "Revenue"

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

# Empty cells or cells with only whitespace

officecli query sheet.xlsx 'cell:empty, cell:contains(" ")' --json

```

### Hierarchical Queries

Restrict searches to specific document structures:

```bash

# Direct child shapes of slides (exclude nested groups)

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

# Deep search for any picture inside any slide

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

```

### Regex Pattern Matching

Use the `~=` operator for partial attribute matches:

```bash

# Cells with formulas containing "SUM"

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

```

### Programmatic JSON Processing

Pipe results to `jq` for metric extraction:

```bash

# Count matching shapes

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

```

## Summary

- The `query` command parses CSS-like selectors through [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs) after CLI dispatch from [`CommandBuilder.GetQuery.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.GetQuery.cs).
- **Implicit AND** combines multiple predicates inside single brackets `[attr1>val1 attr2<val2]`.
- **Explicit OR** uses comma-separated selectors `elem1, elem2` to union result sets.
- Pseudo-selectors `:contains`, `:empty`, and `:no-alt` filter by content analysis.
- Combinators `>` (child) and space (descendant) navigate OOXML hierarchies.
- The `~=` operator enables regex-style attribute matching for partial text searches.

## Frequently Asked Questions

### How do I perform an OR operation between different attribute conditions on the same element?

Use comma-separated selector strings with repeated element names. For example, `row[Score>90], row[Status="Priority"]` returns rows where either the score exceeds 90 or the status equals Priority. Note that `row[Score>90 Status="Priority"]` would require both conditions simultaneously due to implicit AND.

### Are selector names case-sensitive in OfficeCLI?

No. According to the implementation in [`AttributeFilter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/AttributeFilter.cs), the engine normalizes element names and attribute keys to lowercase early in the parsing pipeline. `Row`, `ROW`, and `row` match identically, as do `Score` and `score` in attribute predicates.

### Why does my boolean query with spaces fail?

Spaces inside attribute brackets indicate implicit AND, but spaces outside brackets represent the descendant combinator. Ensure you quote selectors containing spaces in attribute values: `paragraph:contains("Q1 Report")`. Without quotes, the shell may fragment the selector before it reaches the parser.

### Can I use the NOT operator in OfficeCLI queries?

Direct logical NOT is not implemented as a prefix operator. Instead, use inequality operators (`!=`) inside attribute brackets or chain `:empty` pseudo-selectors to exclude elements. For complex negations, pipe results to external tools like `jq` to filter the returned JSON array.