# How to Use CSS‑Like Query Selectors with Boolean Conditions in OfficeCLI

> Master OfficeCLI's CSS-like query selectors with boolean conditions to target Word, Excel, and PowerPoint elements precisely from the command line. Automate document tasks efficiently.

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

---

**OfficeCLI supports a CSS‑inspired selector syntax with Boolean AND/OR logic to target specific elements across Word, Excel, and PowerPoint documents from the command line.**

The **OfficeCLI** open‑source project provides a powerful query language for addressing document elements using familiar CSS patterns. According to the iOfficeAI/OfficeCLI source code, the selector engine tokenizes strings, parses attribute conditions with Boolean operators, and matches pseudo‑selectors—all implemented in the [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs) parser and invoked through [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs).

## Understanding the Selector Grammar

The selector language in OfficeCLI follows a predictable pipeline defined in [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs). Mastering these four stages lets you construct precise queries without trial and error.

### Tokenization and Child Combinators

The raw selector string is first split on the child combinator `>` while respecting bracket boundaries. This happens in the `SplitChildCombinator` method (lines 31‑55 of [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs)).

```bash

# Descend from table → row → cell

officecli query --selector 'table > row[Score>80] > cell[Column="Total"]'

```

Each `>` introduces a new level in the document hierarchy, identical to CSS descendant navigation.

### Element Names and Attribute Filters

After tokenization, `ParseSingleSelector` (lines 63‑84) extracts:

1. The element name (e.g., `row`, `p`, `cell`)
2. Attribute filters inside `[` … `]` brackets

```bash

# Element-only selector

officecli query --selector 'row'

# Element with attribute condition

officecli query --selector 'row[Score>80]'

```

## Boolean Conditions in Attribute Selectors

OfficeCLI implements two explicit Boolean operators for combining conditions: **AND** (comma) and **OR** (pipe).

### AND Logic with Commas

Multiple attribute clauses within the same bracket pair are evaluated as logical AND. The `AttributeFilter.FilterSelector` method (invoked from [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) lines 2078‑2088) processes each condition sequentially.

```bash

# Both conditions must match: Score > 80 AND Status equals "Approved"

officecli query --selector 'row[Score>80,Status="Approved"]'

```

### OR Logic with the Pipe Operator

The pipe character `|` creates alternative matches. Internally, the engine splits these into separate `AttributeFilter` evaluations and merges results.

```bash

# Either condition matches: Dept is "HR" OR "Finance"

officecli query --selector 'row[Dept="HR"|Dept="Finance"]'

```

### Supported Comparison Operators

| Operator | Meaning | Example |
|----------|---------|---------|
| `=` | Equals | `Name="Budget"` |
| `!=` | Not equals | `Status!="Draft"` |
| `<` | Less than | `Score<100` |
| `<=` | Less than or equal | `Score<=100` |
| `>` | Greater than | `Score>80` |
| `>=` | Greater than or equal | `Score>=80` |

These operators are validated during parsing; malformed selectors trigger errors from [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) line 2078.

## Pseudo‑Selectors for Content Matching

The `ParseSingleSelector` method (lines 106‑122) recognizes three CSS‑style pseudo‑selectors stored in the `SelectorPart` struct.

### :contains("text")

Match elements containing specific text content.

```bash

# Find paragraphs containing "budget"

officecli query --selector 'p:contains("budget")'

```

### :empty

Select elements with no content.

```bash

# Find empty table cells

officecli query --selector 'cell:empty'

```

### :no-alt

Target images or objects lacking alternative text descriptions.

## Complete Query Examples

Combine all syntax elements for production workflows:

```bash

# Numeric threshold with string equality (AND)

officecli query --selector 'row[Score>80,Active=true]'

# Cross-department search with OR logic

officecli query --selector 'row[Dept="HR"|Dept="Finance"|Dept="IT"]'

# Hierarchical navigation with conditions

officecli query --selector 'table > row[Score>80] > cell:empty'

# Content search within qualified elements

officecli query --selector 'table > row[Approved=true] > p:contains("signed")'

```

## Error Handling and Debugging

Empty selectors throw immediate validation errors with a ready‑to‑copy correction example:

```json
{"command":"query","selector":"row[Score>80]"}

```

When parsing fails during streaming operations, the `try…catch` block in [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) (line 330) silently skips malformed selectors. Enable verbose output to surface these issues:

```bash
officecli query --selector 'row[Score>80]' --verbose

```

## Key Implementation Files

| File | Responsibility | Key Methods |
|------|--------------|-------------|
| [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs) | Selector grammar parsing | `SplitChildCombinator`, `ParseSingleSelector`, `MatchesParagraphAttrs`, `MatchesRunSelector` |
| [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) | Request routing and filter invocation | `AttributeFilter.FilterSelector` call at line 2078 |
| [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) | Client‑side error suppression | Exception handling at line 330 |

These files implement the complete CSS‑like selector engine that powers OfficeCLI's document querying capabilities.

## Summary

- **Element selection** uses familiar names (`row`, `p`, `cell`, `table`) parsed by `ParseSingleSelector` in [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs)
- **Boolean AND** combines conditions with commas inside brackets: `[Score>80,Status="Approved"]`
- **Boolean OR** uses the pipe operator: `[Dept="HR"|Dept="Finance"]`
- **Comparison operators** include `=`, `!=`, `<`, `<=`, `>`, `>=` evaluated by `AttributeFilter.FilterSelector`
- **Pseudo‑selectors** `:contains()`, `:empty`, and `:no-alt` extend matching to content and metadata
- **Child combinators** (`>`) enable hierarchical navigation through document structures

## Frequently Asked Questions

### What happens if I use an invalid selector string?

OfficeCLI validates selectors early in [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs). An empty or malformed selector throws an error with a JSON example showing correct syntax. During streaming operations, [`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js) catches parsing exceptions and silently skips offending elements unless `--verbose` is enabled.

### Can I mix AND and OR conditions in one selector?

Yes. You can chain multiple bracket blocks or use the pipe operator inside brackets. For complex logic, prefer explicit grouping: `row[Dept="HR"|Dept="Finance"][Active=true]` selects active rows from either department.

### Do pseudo‑selectors work with all document types?

The [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs) implementation provides `:contains("text")`, `:empty`, and `:no-alt` for Word documents. Analogous parsers for Excel and PowerPoint implement equivalent pseudo‑selectors appropriate to those formats.

### Is the selector syntax case‑sensitive?

Element names and attribute keys follow the document model conventions. String comparisons in attribute filters respect the case of the stored values—use consistent casing in your selectors or combine multiple OR conditions to match variations.