{
  "category": "Web functions",
  "display_name": "FILTERXML",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.FILTERXML",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 83 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 83 recorded answers",
    "workbook_corpus": {
      "cells": 83,
      "matched": 83
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L939-L939",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L702-L778",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L780-L797",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L799-L821",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L823-L857",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L859-L895",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L897-L917"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/text_format::read_value",
        "catalogue/text_format::value",
        "catalogue/text_format::profile",
        "catalogue/text_format::rendered",
        "catalogue/text_format::text",
        "decimal::low32",
        "decimal::Natural::zero",
        "decimal::Natural::from_u64",
        "decimal::Natural::pow10",
        "decimal::Natural::normalize",
        "decimal::Natural::is_zero",
        "decimal::Natural::mul_add_small",
        "decimal::Natural::times_pow10",
        "decimal::Natural::times_pow5",
        "decimal::Natural::times_pow2",
        "decimal::ExactDecimal::read",
        "decimal::ExactDecimal::binary",
        "format/datetime::has_invalid_exponent",
        "format/datetime::looks_like_datetime_format",
        "format/datetime::without_subseconds",
        "format/datetime::render_with_datetime_tokens",
        "format/datetime::tokenize_datetime_format",
        "format/datetime::elapsed_token_at",
        "format/datetime::classify_minute_tokens",
        "format/datetime::token_kind",
        "format/datetime::is_time_neighbor",
        "format/datetime::push_literal",
        "format/datetime::render_datetime_literal",
        "format/datetime::format_elapsed",
        "format/datetime::TimeParts::from_serial",
        "format::measured_host",
        "format::currency_literal",
        "format::digits",
        "format::fifteen",
        "format::split",
        "format::grouped",
        "format::general",
        "format::significant",
        "format::sections",
        "format::bracket",
        "format::is_condition",
        "format::is_elapsed",
        "format::condition_holds",
        "format::condition_of",
        "format::strip_tokens",
        "format::choose",
        "format::items",
        "format::numeric",
        "format::literal_text",
        "format::integer_part",
        "format::fraction_part",
        "format::scientific",
        "format::fraction_code",
        "format::FractionCode::render",
        "format::mixed_fraction_under_space_grouping",
        "format::convergent",
        "format::text_declared_date_locale",
        "format::text",
        "format::text_of_text",
        "format/names::month_name",
        "format/names::weekday_name",
        "format/names::locale_names",
        "locale::LocaleId::from_bcp47_language_tag",
        "locale::LocaleId::from_excel_lcid",
        "locale::short_date_order",
        "locale::short_date_pattern",
        "locale::currency_placement",
        "locale::currency_spacing",
        "locale::currency_negative_pattern",
        "locale::format_profile",
        "locale::days_from_civil",
        "locale::civil_from_days",
        "locale::ymd_from_excel_serial",
        "number_text::decimal",
        "number_text::first_precision",
        "number_text::near_tie",
        "number_text::first_rounding",
        "number_text::rounded",
        "number_text::increment",
        "number_text::ascii",
        "ported/date_kernels::days_from_civil",
        "ported/date_kernels::civil_from_days",
        "ported/date_kernels::serial_unbounded_1900",
        "ported/date_kernels::ymd_1900",
        "ported/date_kernels::is_leap",
        "ported/date_kernels::days_in_month",
        "ported/date_kernels::whole_serial",
        "ported/date_kernels::whole",
        "ported/date_kernels::weekday_sunday_one_based",
        "ported/date_kernels::remap_weekday",
        "ported/date_kernels::weekday_of",
        "ported/date_kernels::weekday",
        "ported/text_kernels::text",
        "ported/text_kernels::text_from_str",
        "ported/text_kernels::date_integer_floor",
        "ported/text_kernels::push_singleton_or_original",
        "ported/text_kernels::push_upper",
        "ported/text_kernels::upper",
        "value_text::measured_host_reader",
        "value_text::measured_space",
        "value_text::read",
        "value_text::number",
        "value_text::decimal",
        "value_text::fraction",
        "value_text::tokens",
        "value_text::month_named",
        "value_text::time_at",
        "value_text::full_year",
        "value_text::valid_day",
        "value_text::this_year",
        "value_text::serial_1900",
        "value_text::date_of",
        "value_text::date_time"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_format.rs#L939-L939",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 83 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.FILTERXML.json",
  "name": "FILTERXML",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n\n- **`WEBSERVICE`** — the usual supplier of the `xml` argument. Microsoft's documented idiom is\n  `=FILTERXML(WEBSERVICE(\"…\"&ENCODEURL(C2)), \"//path\")`, which is the three Web functions used\n  as a pipeline: encode, fetch, parse.\n- **`ENCODEURL`** — the first stage of that same pipeline.\n- **Power Query / Get & Transform** — the modern replacement for this workflow, and the one\n  Microsoft steers users toward for anything beyond a single small document. Power Query is not\n  a function, so it does not appear in this catalog, but it is the honest answer to \"should I\n  build on `FILTERXML`?\"\n- **`TEXTSPLIT`, `TEXTBEFORE`, `TEXTAFTER`** — what people use to hack XML apart when\n  `FILTERXML` is unavailable (notably on Mac). Structurally wrong for XML, but portable.\n- **`WEBSERVICE` returning JSON** — a frequent confusion. `FILTERXML` parses XML only; there is\n  no built-in JSON equivalent in the worksheet function surface.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- The XPath dialect and version are unstated. Windows' MSXML supports XPath 1.0; whether Excel\n  exposes anything beyond that is unknown to the Handbook. XPath 1.0 versus 2.0 differ in ways\n  that are observable from a worksheet (sequence handling, string functions, node comparison),\n  so this is not a detail.\n- Namespace handling is the largest single source of behavioural surface, and Microsoft\n  documents exactly one line about it — that an invalid prefix yields `#VALUE!`. Everything\n  else, including default-namespace behaviour, must be pinned by observation.\n- The result shape is host-adapted. The function returns a node sequence; whether that spills,\n  scalarizes by implicit intersection, or fills an array-entered range is a publication-stage\n  question, not a kernel question.\n- Text normalization (whitespace, entity decoding, CDATA) is a per-node decision that a\n  compatibility implementation must copy rather than choose.\n- A `SafePure` classification for an XML parser is a strong claim about the parser: no external\n  entity resolution, no DTD fetching, no network. An implementation that hands the document to\n  a permissive parser inherits an entity-expansion attack surface the worksheet author never\n  asked for.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nText, one value per selected node, spilling on Excel builds that support dynamic arrays.\n\n- **No match.** An XPath that selects nothing. Microsoft's page does not state the result; the\n  Handbook does not know whether it is `#VALUE!`, `#N/A`, or an empty result, and will not\n  guess. It is the first probe below.\n- **Attribute versus element selection.** Both are expressible; whether they are returned\n  identically as text is undocumented.\n- **Whitespace and entities.** Whether the returned text is the raw node content, the\n  whitespace-normalized string value, or the entity-decoded value is not stated anywhere in the\n  documentation, and the three differ for real documents.\n\n\n\n### Errors\n\n\nAs documented by Microsoft on the page linked below:\n\n- **`#VALUE!`** — `xml` is not valid.\n- **`#VALUE!`** — `xml` contains a namespace with a prefix that is not valid.\n\nBoth documented conditions concern the *document*; nothing is documented about a malformed\n`xpath`, which is the more common author error. That gap is listed as a probe.\n\nThe platform restriction is firmly documented and is arguably the most important fact for a\nworkbook author: `FILTERXML` is **not available in Excel for the web or Excel for Mac**.\nMicrosoft adds that it \"may appear in the function gallery in Excel for Mac, but it relies on\nfeatures of the Windows operating system, so it will not return results on Mac\". A function\npresent in the gallery that silently does not work is a distinct and badly signposted state,\nand it makes `FILTERXML` a poor choice for any workbook that will be shared across platforms.\n\n\n",
    "sources": "- Microsoft, \"FILTERXML function\" —\n  <https://support.microsoft.com/en-us/office/filterxml-function-4df72efc-11ec-4951-86f5-c1374812f5b7>\n  (syntax, both argument definitions, the two documented `#VALUE!` conditions, and the\n  Mac/web availability statement quoted above).\n- Microsoft, \"ENCODEURL function\" —\n  <https://support.microsoft.com/en-us/office/encodeurl-function-07c7fb90-7c60-4bff-8687-fac50fe33d0e>\n  (the composed three-function example).\n- Handbook `data/presence/FUNC.FILTERXML.json` — the implementing module\n  `earlier-implementation/web_text_xml_family.rs` and its surface-dispatch entry.\n- Handbook `content/model/01-value-universe.md`, `02-coercion-and-lifting.md` and\n  `03-call-pipeline.md` — the text cap and its two enforcement paths, the text-to-number\n  conversion rule, and the host-side spill adaptation referenced above.\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`FILTERXML` is an XPath engine wearing a worksheet function's clothes. It takes an XML document\n*as text* and an XPath expression *as text*, and returns the node set the expression selects.\nIt makes no network request of its own; the network is `WEBSERVICE`'s job.\n\nThat said, \"bounded\" is doing more work here than it does for `ENCODEURL`. A faithful\n`FILTERXML` requires an XML parser and an XPath processor, and Excel's is the Windows one.\n\n\n\n`FILTERXML(xml, xpath)` parses `xml` and evaluates `xpath` against it, returning the selected\nresult.\n\nThe part that decides how the function behaves in a worksheet is what happens to a node set\nwith more than one node. `FILTERXML` returns **all** matching nodes, not the first one: on a\nmodern Excel the result spills down a column, and on a pre-dynamic-array Excel the same formula\nreturns only the top-left value unless entered as an array formula over a range. The same\nworkbook can therefore appear to behave differently on two Excel versions with no change to the\nformula — this is a spill-adaptation difference at the host boundary (see\n[the call pipeline](../model/03-call-pipeline.md)), not a difference in the function.\n\nThe second decisive fact is that the result is **text**. Nodes selected out of XML come back as\nstrings, whatever they look like. `//price` returning `12.50` gives you the four-character text\n`12.5`-style content, not a number, and `//date` gives you an ISO date string, not a serial.\nArithmetic downstream needs an explicit conversion, and text that does not read as a number is\na named coercion failure rather than a silent zero — see\n[coercion and lifting](../model/02-coercion-and-lifting.md).\n\nXPath is a real language, not a path syntax: predicates (`//item[@id='3']`), axes, and the\nnode/attribute distinction (`//book/@isbn` selects attributes) are all available. That\nexpressiveness is why `FILTERXML` remains useful even though Power Query supersedes it for\nserious ingestion work.\n\n\n\n### Arguments\n\n- **`xml`** (required) — Microsoft: \"A string in valid XML format\". The whole document, as one\n  text value. In practice that value comes from a `WEBSERVICE` call or from a cell, and the\n  cell route imposes the 32,767-code-unit text cap described in\n  [the value universe](../model/01-value-universe.md). That cap is the practical size limit on\n  what `FILTERXML` can be given, and it is small for real-world XML.\n- **`xpath`** (required) — Microsoft: \"A string in standard XPath format\".\n\nThe argument most often misunderstood is `xml`, and specifically the assumption that it can be\na *file*. It cannot. There is no path form, no URL form, and no streaming form; the document\nmust already be a string in the worksheet.\n\nThe second trap is namespaces. Documents that declare a default namespace need the XPath to\naccount for it, and the usual `local-name()` workaround is verbose enough that many users\nconclude `FILTERXML` is broken when it is behaving correctly.\n\n\n"
  },
  "signature": {
    "display": "FILTERXML(xml, xpath)",
    "parameters": [
      {
        "description": null,
        "name": "xml",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "xpath",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 2,
        "min": 2
      },
      "category": "Web functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "None",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Values picked out of XML text by an XPath expression",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns specific data from the XML content by using the specified XPath",
        "microsoft_url": "https://support.microsoft.com/en-us/office/filterxml-function-4df72efc-11ec-4951-86f5-c1374812f5b7"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "FILTERXML"
        },
        {
          "locale": "bg-BG",
          "name": "FILTERXML"
        },
        {
          "locale": "cs-CZ",
          "name": "FILTERXML"
        },
        {
          "locale": "da-DK",
          "name": "FILTRERXML"
        },
        {
          "locale": "de-DE",
          "name": "FILTERXML"
        },
        {
          "locale": "el-GR",
          "name": "FILTERXML"
        },
        {
          "locale": "en-AU",
          "name": "FILTERXML"
        },
        {
          "locale": "en-GB",
          "name": "FILTERXML"
        },
        {
          "locale": "en-US",
          "name": "FILTERXML"
        },
        {
          "locale": "es-ES",
          "name": "XMLFILTRO"
        },
        {
          "locale": "et-EE",
          "name": "FILTERXML"
        },
        {
          "locale": "fi-FI",
          "name": "SUODATA.XML"
        },
        {
          "locale": "fr-FR",
          "name": "FILTRE.XML*"
        },
        {
          "locale": "he-IL",
          "name": "FILTERXML"
        },
        {
          "locale": "hr-HR",
          "name": "FILTERXML"
        },
        {
          "locale": "hu-HU",
          "name": "XMLSZŰRÉS"
        },
        {
          "locale": "id-ID",
          "name": "FILTERXML"
        },
        {
          "locale": "it-IT",
          "name": "FILTERXML"
        },
        {
          "locale": "ja-JP",
          "name": "FILTERXML"
        },
        {
          "locale": "ko-KR",
          "name": "FILTERXML"
        },
        {
          "locale": "lt-LT",
          "name": "FILTERXML"
        },
        {
          "locale": "lv-LV",
          "name": "FILTERXML"
        },
        {
          "locale": "nb-NO",
          "name": "FILTERXML"
        },
        {
          "locale": "nl-NL",
          "name": "FILTERXML"
        },
        {
          "locale": "pl-PL",
          "name": "FILTERXML"
        },
        {
          "locale": "pt-BR",
          "name": "FILTERXML"
        },
        {
          "locale": "pt-PT",
          "name": "FILTRARXML"
        },
        {
          "locale": "ro-RO",
          "name": "FILTERXML"
        },
        {
          "locale": "ru-RU",
          "name": "ФИЛЬТР.XML"
        },
        {
          "locale": "sk-SK",
          "name": "FILTERXML"
        },
        {
          "locale": "sl-SI",
          "name": "FILTERXML"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "FILTERXML"
        },
        {
          "locale": "sv-SE",
          "name": "FILTERXML"
        },
        {
          "locale": "th-TH",
          "name": "FILTERXML"
        },
        {
          "locale": "tr-TR",
          "name": "XMLFİLTRELE"
        },
        {
          "locale": "uk-UA",
          "name": "FILTERXML"
        },
        {
          "locale": "vi-VN",
          "name": "FILTERXML"
        },
        {
          "locale": "zh-CN",
          "name": "FILTERXML"
        },
        {
          "locale": "zh-HK",
          "name": "FILTERXML"
        },
        {
          "locale": "zh-TW",
          "name": "FILTERXML"
        }
      ],
      "signature": {
        "display": "FILTERXML(xml, xpath)",
        "parameters": [
          {
            "description": null,
            "name": "xml",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "xpath",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "FILTERXML",
      "version_marker": null,
      "xlcall": {
        "code": "595",
        "symbol": "xlfFilterxml"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/filterxml-function-4df72efc-11ec-4951-86f5-c1374812f5b7"
  },
  "try_it": {
    "formula": "=FILTERXML(\"<root><item>hello</item></root>\",\"/root/item\")"
  },
  "url": "https://handbook.dnacalc.com/functions/FILTERXML.html",
  "variants": [],
  "versions": []
}