



  

<!DOCTYPE html>
<html
  lang="en"
  
  data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
  data-a11y-animated-images="system" data-a11y-link-underlines="true"
  
  >




  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
  <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
  <link rel="preconnect" href="https://avatars.githubusercontent.com">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-5c4e9fc574bf49f3.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-fb37c309e0603a69.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-0f910d8806d5761b.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-a7abd4d4c49ac593.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-5fc4c4a9cb41e596.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-ed0cee9214dedabd.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-afff6c53aef9b9d1.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-c409873d7987dffa.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-78a2491d538dab5a.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-c26b63d7c532d0a2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-a6f60cea68c08405.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-f66faf28b2ea18b6.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-6701f6218c53cf5b.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-7037fa46ae124d97.css" />

  <style type="text/css">
    :root {
      --tab-size-preference: 4;
    }

    pre, code {
      tab-size: var(--tab-size-preference);
    }
  </style>

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-97df7784617ce1ea.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-9be9fe6313f476af.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-62747e27e61258dc.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-7a418ea859d1654d.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-72bd7d974b5ac1cc.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-4c5c0895f723f870.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_caches_react_shell","actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","actions_runners_react_shell","activity_diff_file_tree","activity_repos_file_tree","activity_repos_overview_header","activity_repos_overview_sidebar","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_automation_repo_mcp_servers","copilot_automations_pagination","copilot_base_model_policy_row","copilot_chat_auto_mode_v2","copilot_chat_clear_model_selection_for_default_change","copilot_chat_early_task_provisioning","copilot_chat_persist_session_drafts","copilot_chat_vision_dotcom_chat_ga_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_hide_hovercard","copilot_immersive_task_hyperlinking","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_awps_batching","copilot_mission_control_early_stop","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_discussion_comment_trigger","copilot_swe_agent_discussion_opened_trigger","copilot_swe_agent_discussion_updated_trigger","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_assigned_trigger","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_issue_labeled_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_assigned_trigger","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_labeled_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_ready_for_review_trigger","copilot_swe_agent_pull_request_review_requested_trigger","copilot_swe_agent_pull_request_review_submitted_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_sub_issue_added_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_workbench_sunset_redirect","dashboard_agents_module_auth_token_check","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","fgpat_permissions_selector_redesign","glc_code_quality_repo_settings_workflow_config","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_ubb_individual_budget_banner","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_team_vs_personal","issue_relative_time_micro","issues_dashboard_sso_structured_errors","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_index_data_router","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_cookie_consent_banner","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_queue_restricted_pushers_warning","merge_status_header_feedback","milestone_closed_issues_prioritization","milestone_show_data_router","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_copilot_attribution_header","pull_request_overview_merge_control","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_navigation_shortcuts","pull_request_virtualization_image_estimate","pull_request_virtualization_loader_batching","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_logged_out_repository_header","react_query_props_with_key","react_sandbox_future_tanstack","repo_app_turbo","repo_issues_sidebar_layout","repo_pulls_dashboard_declutter","repo_pulls_dashboard_ga","repo_pulls_dashboard_persistence","repo_pulls_dashboard_sidebar_links","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_nav_spark_models_removed","speculation_rules_ui_service","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","update_issue_suggestions","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workstream_plugin_bootstrap"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-b752d992928a526c.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-789f756ca38b5dee.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-2f08c823163591a8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-633ad94fa06c334b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-0fb4c544a797ec0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-7c872b58ac9f1b39.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tp-7e9817cf5c068979.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-4a2eea6c963ceeb7.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.bef03fb24bb03be8.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-52ed81112a548e10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e8810f64c443fb9b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-0417f617ad744a0d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-9da36843ba9d191d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-9a1160b939f2cd52.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3h-55903cf2303047ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hk-f1498fec45311acd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-7aa1ff0a0e750f41.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-1d800d09e9a8720a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-9697c1c8f5cbf523.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-ad3b8b99367a3725.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-ad2b49a16d2a4933.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-5e0b3ae3c4036207.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-524a06aa946df6fc.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-b1ee53c2200b172a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-7bf7b9d689fe3d10.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a9-ca3bc10b816bcc1f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-21ec1e439ee2d87c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t-4c39f7195fc42cc8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pb-53cfff089eaac51b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6n-afcf86ccabc4cad2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zj-4d9cf83cf08e1643.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wo-6991af5b3829ffe8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/nfv-a6c14301d3ea6d67.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b5-a2fde30ce0c692b9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sw-9d0489dbf9a9c942.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ttf-7d5abe1b447ced2c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sj-c7a44023ee90d468.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0pd-c46d8dfae89c2b64.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-50d165856436f839.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.255cab819a92f7e1.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-9a54c2ca617029eb.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-8503588299651923.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-66e64888bc4615bb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qmp-c7cfba40cf5a93b0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-148a74299e5a01ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-a9404625ec30bbc7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4u-8f9f1d6be01d6a22.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/s0-68d09e5e8a80cb94.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y5-0cb3f75cec297941.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4u-cd9039ad946274ad.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8s-00bd469c4017a543.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-27679061f16e1495.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/iu-2d03f5e6d4fdd54d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gru-2b0fac8887ff8c57.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/a0-234e967e7c6d22ce.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gz3-5bdfbfceac967bb6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/15m-64f3034430471048.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/1e-c15441bdb94d54ae.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gzu-6ad9a0527a5d7afd.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bi-3a42b8714e06c4d0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tu1-37e16844272ddefa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b1-ac66ededed061993.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gmn-1e5497c041b66231.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0l5-d1b2a63015b5eb6d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/c2-e85522be441acf73.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/f9-baf0a4193779952e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sp-87dce99c82a27004.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/zkm-116b01b8485bbe3f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/og-518d12c9e011601d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b9-947db365ea875cfa.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/14-8c7b4ad3c845664c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dsj-2e7d883cb843e9e6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ec-38012819307fd539.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/du-6607da3b8b579202.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/20-f43eb09c2be69457.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ql0-107312645ac2b72d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-fa7cdc0f7656d876.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p0l-fe491d943adf7508.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/v1e-d099d9fd21ad25e5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fn-7b298a45c55fb6fb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7cw-6e493a20eaaa04b5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ok-290e4b9465ba9c5b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6d-ca6d584a0fd6368c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/y8-e2f18f5a24733f3b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xc-3fd4a2e7dcbad8e2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/vjg-2874f95f389c4d3f.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-00b4e67334a0c652.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/xc.de2b1dde0494f261.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.0ffb5e588b18e1a5.module.css" />


  <title>xmloxide/MIGRATION.md at main · jonwiggins/xmloxide · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:d545c3a4-6ab5-4bdd-0839-db1c39da8369">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="A99A:1757F1:3E6498:3ABD39:6AC748B8" data-pjax-transient="true"/><meta name="html-safe-nonce" content="ff8a5731b468033efe67ee1470ae9267a8901ed7c48f0c6fbdc8067bd5aba5f4" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBOTlBOjE3NTdGMTozRTY0OTg6M0FCRDM5OjZBQzc0OEI4IiwidmlzaXRvcl9pZCI6IjUyMjY3NDU0MzYzOTYxMTU3NiIsInJlZ2lvbl9lZGdlIjoiZnJhIiwicmVnaW9uX3JlbmRlciI6ImZyYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="d9713a1b903499951ce8ade77d906a985d18d08ce9876ccb0f56a6ec5caebc53" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:1163839325" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" data-turbo-transient>
  <link rel="assets" href="https://github.githubassets.com/">

    <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">

<meta name="octolytics-url" content="https://collector.github.com/github/collect" />





  <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="A pure Rust reimplementation of libxml2. Contribute to jonwiggins/xmloxide development by creating an account on GitHub.">

      <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">

    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <meta property="fb:app_id" content="1401488693436528">
    <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md" />

      <meta name="twitter:image" content="https://opengraph.githubassets.com/142d9e9656c232108dc085e3b4f2f358dcd66bf4306d3444d96ecf0177f18c1f/jonwiggins/xmloxide" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="xmloxide/MIGRATION.md at main · jonwiggins/xmloxide" /><meta name="twitter:description" content="A pure Rust reimplementation of libxml2. Contribute to jonwiggins/xmloxide development by creating an account on GitHub." />
  <meta property="og:image" content="https://opengraph.githubassets.com/142d9e9656c232108dc085e3b4f2f358dcd66bf4306d3444d96ecf0177f18c1f/jonwiggins/xmloxide" /><meta property="og:image:alt" content="A pure Rust reimplementation of libxml2. Contribute to jonwiggins/xmloxide development by creating an account on GitHub." /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="xmloxide/MIGRATION.md at main · jonwiggins/xmloxide" /><meta property="og:url" content="https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md" /><meta property="og:description" content="A pure Rust reimplementation of libxml2. Contribute to jonwiggins/xmloxide development by creating an account on GitHub." />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="e111fc5d953c4ccc9fe372ee3ca9af49938847212708009cd003a8f459b40d99" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="c4a65e47b0c850e1157ae8e66298070851d7e3b558038de5a3b4ff7a93e630ed" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="1ff3f1d4e1abd61f6f135b47d3b815e2f7169f8dd418f0118c6b1cf4de6cbc86" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="05282bf7f52de6d856d8251fd23b4d998d5520c9372a47808b9acf91a77386e0" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/jonwiggins/xmloxide git https://github.com/jonwiggins/xmloxide.git">

  <meta name="octolytics-dimension-user_id" content="35540058" /><meta name="octolytics-dimension-user_login" content="jonwiggins" /><meta name="octolytics-dimension-repository_id" content="1163839325" /><meta name="octolytics-dimension-repository_nwo" content="jonwiggins/xmloxide" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="1163839325" /><meta name="octolytics-dimension-repository_network_root_nwo" content="jonwiggins/xmloxide" />
  



    

    <meta name="turbo-body-classes" content="logged-out env-production page-responsive">
  <meta name="disable-turbo" content="false">


  <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">


  <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

  <meta name="release" content="7dbf834a08f035e635ac14386e0657498aa6b451" data-turbo-track="reload">
  <meta name="ui-target" content="full">

  <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
  <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
  <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">

<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />


  <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

  </head>

  <body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
    <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
      <div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
      

    <div class="position-relative header-wrapper js-header-wrapper ">
      <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>

      <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
    <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>      
      <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qc-1bbbe8787ea1cd4b.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-4b95d20f4497e422.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.e2ab74db231fe5a2.module.css" />

<react-partial
  partial-name="keyboard-shortcuts-dialog"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>





      

          <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-install-banner-partial-6c612b51f355f96f.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-install-banner-partial.98ecd74f68dd8e8f.module.css" />

<react-partial
  partial-name="app-install-banner-partial"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>


          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2l-e468179ba7123a2e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/rwd-069fc3d9814ff9fe.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz-e662bc3745e171e7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jag-3559ee48016881a2.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3d-7f22b36f29a9dd94.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tua-4998592d21eb16f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/8i-ea1b3f2e11ed8cd3.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-11ed636a612b7285.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.05b219cdb8e80c43.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/8i.5d9e6dcb0dade694.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Fjonwiggins%2Fxmloxide%2Fblob%2Fmain%2FMIGRATION.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=jonwiggins%2Fxmloxide","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md\",\"user_id\":null}}","auth_hydro_click_hmac":"910876b2dea13aff54ec60577555dd4da169e6a78015cce935906bebc46151d1","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path></svg></a><div class="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fjonwiggins%2Fxmloxide%2Fblob%2Fmain%2FMIGRATION.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="910876b2dea13aff54ec60577555dd4da169e6a78015cce935906bebc46151d1"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path></svg>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg><span class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Fjonwiggins%2Fxmloxide%2Fblob%2Fmain%2FMIGRATION.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="910876b2dea13aff54ec60577555dd4da169e6a78015cce935906bebc46151d1"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=jonwiggins%2Fxmloxide" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="910876b2dea13aff54ec60577555dd4da169e6a78015cce935906bebc46151d1"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
  
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>

    <button id="icon-button-2fd662db-3af3-4e85-9eef-bd3b78791685" aria-labelledby="tooltip-e407e85f-42ad-47c8-bbe2-392f12a532ca" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-e407e85f-42ad-47c8-bbe2-392f12a532ca" for="icon-button-2fd662db-3af3-4e85-9eef-bd3b78791685" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>


  
</div>
    </div>

  <div id="start-of-content" class="show-on-focus"></div>








    <div id="js-flash-container" class="flash-container" data-turbo-replace>






  <template class="js-flash-template">
    
<div class="flash flash-full   {{ className }}">
  <div >
    <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    <div aria-atomic="true" role="alert" class="js-flash-alert">
      
      <div>{{ message }}</div>

    </div>
  </div>
</div>
  </template>
</div>


    






  <div
    class="application-main "
    data-commit-hovercards-enabled
    data-discussion-hovercards-enabled
    data-issue-and-pr-hovercards-enabled
    data-project-hovercards-enabled
  >
        <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
    <main id="js-repo-pjax-container" >
      
      








  

    <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ym-1a7ce813a378e1f7.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mn-bb458474353a279e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t5-26d19272bbf73ca3.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2d5-9abb2f6ba5c935d0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/24-b11e1c4108322883.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mrn-12afac2ecd2be980.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dgq-bbf7670f9cdba2e0.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7w-740b4e942974ccba.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/we-c9f93392098ad6c9.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/775-f58305f9bcded6f1.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bn-fcef0645a47703fc.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xgw-6c6cb7b2ed77f52e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ge-ca1c0ba8656f9680.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9f-3f61950dd9225c4a.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/global-nav-bar-5bc29cc0ec528c19.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.e4334163c54cccf5.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.501e99879e15a48e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-nav-bar.2c2cd1e307dba786.module.css" />

<react-partial
  partial-name="global-nav-bar"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"contextRegion":{"crumbs":[{"crumb_type":"user","label":"jonwiggins","is_root":false,"href":"/jonwiggins"},{"crumb_type":"repository","label":"xmloxide","is_root":false,"href":"/jonwiggins/xmloxide"}],"localNavigation":[{"id":"code","icon":"code","label":"Code","href":"/jonwiggins/xmloxide","selectedLinks":["repo_source","repo_downloads","repo_commits","repo_releases","repo_tags","repo_branches","repo_packages","repo_deployments","repo_attestations"],"popoverTarget":false,"commandId":"repositories:go-to-code","reactNav":{"appTarget":"code-view","anchor":"code-view-repo-link"},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"issues","icon":"issue-opened","label":"Issues","href":"/jonwiggins/xmloxide/issues","selectedLinks":["repo_issues","repo_labels","repo_milestones"],"count":8,"popoverTarget":false,"commandId":"repositories:go-to-issues","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"pull-requests","icon":"git-pull-request","label":"Pull requests","href":"/jonwiggins/xmloxide/pulls","selectedLinks":["repo_pulls","checks"],"count":3,"popoverTarget":false,"commandId":"repositories:go-to-pull-requests","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"actions","icon":"play","label":"Actions","href":"/jonwiggins/xmloxide/actions","selectedLinks":["repo_actions"],"popoverTarget":false,"commandId":"repositories:go-to-actions","reactNav":{"appTarget":"actions-workflows","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"projects","icon":"table","label":"Projects","href":"/jonwiggins/xmloxide/projects","selectedLinks":["repo_projects","new_repo_project","repo_project"],"popoverTarget":false,"commandId":"repositories:go-to-projects","reactNav":{"appTarget":"repo","anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"security-and-quality","icon":"shield","label":"Security and quality","href":"/jonwiggins/xmloxide/security","selectedLinks":["security","overview","alerts","policy","token_scanning","code_scanning"],"count":0,"popoverTarget":false,"commandId":"repositories:go-to-security","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}},{"id":"insights","icon":"graph","label":"Insights","href":"/jonwiggins/xmloxide/pulse","selectedLinks":["repo_graphs","repo_contributors","dependency_graph","dependabot_updates","pulse","people","community"],"popoverTarget":false,"commandId":"repositories:go-to-insights","reactNav":{"appTarget":null,"anchor":null},"turboNav":{"frame":"repo-content-turbo-frame"}}],"localNavigationUpdateChannel":null,"selectedLink":"repo_source"},"owner":null,"headerLogo":{"href":"/","aria-label":"Homepage "},"notifications":{"indicatorMode":"disabled","websocketChannel":null,"fetchIndicatorSrc":"/notifications/indicator","fetchIndicatorEnabled":false},"issues":{"href":"/issues"},"pulls":{"href":"/pulls"},"contributedRepos":{"href":"/repos"},"copilot":{"show":false,"showAgentsButton":false,"showRelaunchAnnouncement":false,"copilotChatUrl":null,"copilotApiUrl":"https://api.githubcopilot.com"},"search":{"show":true,"showCommandPalette":false,"isSearchPage":false,"isJumpToSearch":false,"searchContext":{"scope":"repo:jonwiggins/xmloxide","current_repo_name":"xmloxide","current_repo_nwo":"jonwiggins/xmloxide","user_id":"jonwiggins"}},"commandPalette":null,"enterpriseBar":{"show":false},"globalTransactionalMessage":[],"payloadsUrl":"/_global-navigation/payloads.json?can_toggle_site_admin_and_employee_status=0\u0026is_admin_mode_on=0\u0026is_ui_opted_out=0\u0026show_ui_opt_out=0\u0026v=6","contextRegionUrl":"/_global-navigation/context-region.json"}}</script>
  <div data-target="react-partial.reactRoot"><header aria-label="Global navigation menu" data-component="Stack" class="GlobalNav styles-module__appHeader__YzYWk prc-Stack-Stack-UQ9k6" data-gap="none" data-direction="vertical" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="none"><div data-component="Stack" class="prc-Stack-Stack-UQ9k6" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="center" data-padding="none"><div data-testid="top-nav-center" data-component="Stack" class="styles-module__center__R3QRv styles-module__withLocalNavigation__rjTJ_ GlobalNavBar-module__loggedOut__Jv1rk prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="stretch" data-wrap="nowrap" data-justify="start" data-padding="normal"><nav class="styles-module__contextRegion__VbSp2 prc-Breadcrumbs-BreadcrumbsBase-3Gb-B" aria-label="Breadcrumbs" data-overflow="menu" data-variant="normal" data-component="Breadcrumbs"><ol class="prc-Breadcrumbs-BreadcrumbsList-BKjpe"><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/jonwiggins" data-discover="true"><span class="">jonwiggins</span></a></li><li class="prc-Breadcrumbs-ItemWrapper-k0NLn"><a class="styles-module__contextCrumb__IzGIq prc-Breadcrumbs-Item-jcraJ" data-component="Breadcrumbs.Item" href="/jonwiggins/xmloxide" data-discover="true"><span class="styles-module__contextCrumbLast__tI2e3">xmloxide</span></a></li></ol></nav></div><div data-testid="top-nav-right" data-component="Stack" class="styles-module__right__mlBQg styles-module__withLocalNavigation__rjTJ_ styles-module__rightWithResponsiveCreateButton__SKn2W prc-Stack-Stack-UQ9k6" data-gap="condensed" data-direction="horizontal" data-align="center" data-wrap="nowrap" data-justify="start" data-padding="normal"></div></div><h2 class="prc-src-InternalVisuallyHidden-2YaI6">Repository navigation</h2><nav class="prc-components-UnderlineWrapper-eT-Yj prc-UnderlineNav-UnderlineWrapper-GWONT LocalNavigation-module__LocalNavigation__b0Xc0" aria-label="Repository" data-variant="inset" data-overflow-mode="wrap" data-hide-icons-breakpoint="medium"><ul class="prc-UnderlineNav-ItemsList-oj8gN prc-components-UnderlineItemList-xKlKC" role="list"><li role="presentation" aria-hidden="true" class="prc-UnderlineNav-WrapSpacer--aLgz"></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a aria-current="page" data-tab-item="code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg></span><span data-component="text" data-content="Code">Code</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="issues" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide/issues" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg></span><span data-component="text" data-content="Issues">Issues</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">8</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->8<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="pull-requests" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide/pulls" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-pull-request" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path></svg></span><span data-component="text" data-content="Pull requests">Pull requests</span><span data-component="counter"><span aria-hidden="true" data-variant="secondary" data-component="CounterLabel" class="prc-CounterLabel-CounterLabel-X-kRU">3</span><span class="prc-VisuallyHidden-VisuallyHidden-Q0qSB"> (<!-- -->3<!-- -->)</span></span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="actions" data-react-nav="actions-workflows" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide/actions" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-play" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path></svg></span><span data-component="text" data-content="Actions">Actions</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="projects" data-react-nav="repo" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide/projects" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-table" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path></svg></span><span data-component="text" data-content="Projects">Projects</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="security-and-quality" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide/security" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg></span><span data-component="text" data-content="Security and quality">Security and quality</span></a></li><li class="prc-UnderlineNav-UnderlineNavItem-syRjR"><a data-tab-item="insights" data-turbo-frame="repo-content-turbo-frame" class="prc-components-UnderlineItem-7fP-n" href="/jonwiggins/xmloxide/pulse" data-discover="true"><span data-component="icon"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-graph" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg></span><span data-component="text" data-content="Insights">Insights</span></a></li></ul><div class="prc-UnderlineNav-MoreButtonContainer-Dnrq6"><div class="prc-UnderlineNav-MoreButtonDivider-dN0a-"></div><button data-component="overflow-menu-button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk prc-UnderlineNav-MoreButton-Y8soj" data-loading="false" data-size="medium" data-variant="invisible" id="_R_2ktl_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3"><span>More<span class="prc-src-InternalVisuallyHidden-2YaI6"> items</span></span></span></span><span data-component="trailingAction" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></button></div></nav><div class="d-none"></div></header></div>
</react-partial>


  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/jonwiggins/xmloxide/blob/main/MIGRATION.md"
  style="display: block; min-height: calc(100vh - 64px);"
  data-attempted-ssr="true"
  data-ssr="true"
  data-lazy="false"
  data-alternate="false"
  data-data-router-enabled="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":"Migrating from libxml2 to xmloxide","anchor":"migrating-from-libxml2-to-xmloxide","htmlText":"Migrating from libxml2 to xmloxide"},{"level":2,"text":"Quick start","anchor":"quick-start","htmlText":"Quick start"},{"level":2,"text":"Key differences","anchor":"key-differences","htmlText":"Key differences"},{"level":2,"text":"Before and after","anchor":"before-and-after","htmlText":"Before and after"},{"level":3,"text":"Parsing and inspecting a document","anchor":"parsing-and-inspecting-a-document","htmlText":"Parsing and inspecting a document"},{"level":3,"text":"XPath queries","anchor":"xpath-queries","htmlText":"XPath queries"},{"level":3,"text":"Error handling","anchor":"error-handling","htmlText":"Error handling"},{"level":3,"text":"HTML5 parsing (new in xmloxide)","anchor":"html5-parsing-new-in-xmloxide","htmlText":"HTML5 parsing (new in xmloxide)"},{"level":3,"text":"HTML5 streaming (SAX-like, Rust only)","anchor":"html5-streaming-sax-like-rust-only","htmlText":"HTML5 streaming (SAX-like, Rust only)"},{"level":3,"text":"Schematron validation (new in xmloxide)","anchor":"schematron-validation-new-in-xmloxide","htmlText":"Schematron validation (new in xmloxide)"},{"level":3,"text":"CSS selectors (new in xmloxide, Rust only)","anchor":"css-selectors-new-in-xmloxide-rust-only","htmlText":"CSS selectors (new in xmloxide, Rust only)"},{"level":2,"text":"What's NOT compatible","anchor":"whats-not-compatible","htmlText":"What's NOT compatible"},{"level":2,"text":"Thread safety","anchor":"thread-safety","htmlText":"Thread safety"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMigrating from libxml2 to xmloxide\u003c/h1\u003e\u003ca id=\"user-content-migrating-from-libxml2-to-xmloxide\" class=\"anchor\" aria-label=\"Permalink: Migrating from libxml2 to xmloxide\" href=\"#migrating-from-libxml2-to-xmloxide\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis guide covers how to migrate C/C++ code from libxml2 to xmloxide's C FFI.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eQuick start\u003c/h2\u003e\u003ca id=\"user-content-quick-start\" class=\"anchor\" aria-label=\"Permalink: Quick start\" href=\"#quick-start\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003eReplace \u003ccode\u003e#include \u0026lt;libxml/parser.h\u0026gt;\u003c/code\u003e (etc.) with \u003ccode\u003e#include \"libxml2_compat.h\"\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eRemove \u003ccode\u003exmlInitParser()\u003c/code\u003e / \u003ccode\u003exmlCleanupParser()\u003c/code\u003e calls (they become no-ops)\u003c/li\u003e\n\u003cli\u003eReplace direct struct member access (\u003ccode\u003enode-\u0026gt;name\u003c/code\u003e) with accessor functions\u003c/li\u003e\n\u003cli\u003eBuild and link against \u003ccode\u003elibxmloxide\u003c/code\u003e instead of \u003ccode\u003elibxml2\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eKey differences\u003c/h2\u003e\u003ca id=\"user-content-key-differences\" class=\"anchor\" aria-label=\"Permalink: Key differences\" href=\"#key-differences\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eConcept\u003c/th\u003e\n\u003cth\u003elibxml2\u003c/th\u003e\n\u003cth\u003exmloxide\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eNode access\u003c/td\u003e\n\u003ctd\u003eDereference pointer: \u003ccode\u003enode-\u0026gt;name\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eCall function: \u003ccode\u003exmlNodeGetName(node)\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eNavigation\u003c/td\u003e\n\u003ctd\u003ePointer chain: \u003ccode\u003enode-\u0026gt;parent-\u0026gt;children\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eFunction calls: \u003ccode\u003exmlNodeGetParent(node)\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eNode identity\u003c/td\u003e\n\u003ctd\u003eRaw pointer (\u003ccode\u003exmlNodePtr\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003eHandle struct with \u003ccode\u003e(doc, id)\u003c/code\u003e pair\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eGlobal state\u003c/td\u003e\n\u003ctd\u003eRequired: \u003ccode\u003exmlInitParser()\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eNone needed\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eThread safety\u003c/td\u003e\n\u003ctd\u003eManual synchronization\u003c/td\u003e\n\u003ctd\u003eAutomatic (\u003ccode\u003eSend + Sync\u003c/code\u003e)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eError handling\u003c/td\u003e\n\u003ctd\u003eGlobal/context error handler\u003c/td\u003e\n\u003ctd\u003eThread-local: \u003ccode\u003exmloxide_last_error()\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eString deallocation\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003exmlFree()\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003exmlFree()\u003c/code\u003e (compat) or \u003ccode\u003exmloxide_free_string()\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBefore and after\u003c/h2\u003e\u003ca id=\"user-content-before-and-after\" class=\"anchor\" aria-label=\"Permalink: Before and after\" href=\"#before-and-after\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eParsing and inspecting a document\u003c/h3\u003e\u003ca id=\"user-content-parsing-and-inspecting-a-document\" class=\"anchor\" aria-label=\"Permalink: Parsing and inspecting a document\" href=\"#parsing-and-inspecting-a-document\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003elibxml2:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#include \u0026lt;libxml/parser.h\u0026gt;\n#include \u0026lt;libxml/tree.h\u0026gt;\n\nxmlInitParser();\nxmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);\nxmlNodePtr root = xmlDocGetRootElement(doc);\nprintf(\u0026quot;Root: %s\\n\u0026quot;, root-\u0026gt;name);\n\nfor (xmlNodePtr cur = root-\u0026gt;children; cur; cur = cur-\u0026gt;next) {\n    if (cur-\u0026gt;type == XML_ELEMENT_NODE) {\n        char *content = (char *)xmlNodeGetContent(cur);\n        printf(\u0026quot;  %s: %s\\n\u0026quot;, cur-\u0026gt;name, content);\n        xmlFree(content);\n    }\n}\nxmlFreeDoc(doc);\nxmlCleanupParser();\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003e#include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u0026lt;libxml/parser.h\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003e#include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u0026lt;libxml/tree.h\u0026gt;\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003exmlInitParser\u003c/span\u003e();\n\u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlReadMemory\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ebuf\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003esize\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlDocGetRootElement\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"Root: %s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003ename\u003c/span\u003e);\n\n\u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003echildren\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003enext\u003c/span\u003e) {\n    \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e==\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eXML_ELEMENT_NODE\u003c/span\u003e) {\n        \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e)\u003cspan class=\"pl-en\"\u003exmlNodeGetContent\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"  %s: %s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003ename\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmlFree\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e);\n    }\n}\n\u003cspan class=\"pl-en\"\u003exmlFreeDoc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmlCleanupParser\u003c/span\u003e();\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003exmloxide (with compat header):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#include \u0026quot;libxml2_compat.h\u0026quot;\n\nxmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);\nxmlNodePtr root = xmlDocGetRootElement(doc);\nchar *root_name = xmlNodeGetName(root);\nprintf(\u0026quot;Root: %s\\n\u0026quot;, root_name);\nxmlFree(root_name);\n\nxmlNodePtr cur = xmlNodeGetChildren(root);\nwhile (cur) {\n    if (xmlNodeGetType(cur) == XMLOXIDE_NODE_ELEMENT) {\n        char *name = xmlNodeGetName(cur);\n        char *content = xmlNodeGetContent(cur);\n        printf(\u0026quot;  %s: %s\\n\u0026quot;, name, content);\n        xmlFree(name);\n        xmlFree(content);\n    }\n    xmlNodePtr next = xmlNodeGetNext(cur);\n    xmlFreeNode(cur);\n    cur = next;\n}\nxmlFreeNode(root);\nxmlFreeDoc(doc);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003e#include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"libxml2_compat.h\"\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlReadMemory\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ebuf\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003esize\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlDocGetRootElement\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eroot_name\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlNodeGetName\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"Root: %s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eroot_name\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmlFree\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eroot_name\u003c/span\u003e);\n\n\u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlNodeGetChildren\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e);\n\u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e) {\n    \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-en\"\u003exmlNodeGetType\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e) \u003cspan class=\"pl-c1\"\u003e==\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003eXMLOXIDE_NODE_ELEMENT\u003c/span\u003e) {\n        \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlNodeGetName\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e);\n        \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlNodeGetContent\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"  %s: %s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmlFree\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmlFree\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003econtent\u003c/span\u003e);\n    }\n    \u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enext\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlNodeGetNext\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e);\n    \u003cspan class=\"pl-en\"\u003exmlFreeNode\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e);\n    \u003cspan class=\"pl-s1\"\u003ecur\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enext\u003c/span\u003e;\n}\n\u003cspan class=\"pl-en\"\u003exmlFreeNode\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmlFreeDoc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eKey changes:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNo \u003ccode\u003exmlInitParser()\u003c/code\u003e / \u003ccode\u003exmlCleanupParser()\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eroot-\u0026gt;name\u003c/code\u003e becomes \u003ccode\u003exmlNodeGetName(root)\u003c/code\u003e (returns owned string)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eroot-\u0026gt;children\u003c/code\u003e becomes \u003ccode\u003exmlNodeGetChildren(root)\u003c/code\u003e (returns handle)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecur-\u0026gt;next\u003c/code\u003e becomes \u003ccode\u003exmlNodeGetNext(cur)\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNode handles must be freed with \u003ccode\u003exmlFreeNode()\u003c/code\u003e when done\u003c/li\u003e\n\u003cli\u003eStrings from accessor functions are always owned and must be freed\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eXPath queries\u003c/h3\u003e\u003ca id=\"user-content-xpath-queries\" class=\"anchor\" aria-label=\"Permalink: XPath queries\" href=\"#xpath-queries\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003elibxml2:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"xmlXPathContextPtr ctx = xmlXPathNewContext(doc);\nxmlXPathObjectPtr result = xmlXPathEvalExpression(\u0026quot;//book/title\u0026quot;, ctx);\nif (result \u0026amp;\u0026amp; result-\u0026gt;nodesetval) {\n    for (int i = 0; i \u0026lt; result-\u0026gt;nodesetval-\u0026gt;nodeNr; i++) {\n        xmlNodePtr node = result-\u0026gt;nodesetval-\u0026gt;nodeTab[i];\n        char *text = (char *)xmlNodeGetContent(node);\n        printf(\u0026quot;%s\\n\u0026quot;, text);\n        xmlFree(text);\n    }\n}\nxmlXPathFreeObject(result);\nxmlXPathFreeContext(ctx);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003exmlXPathContextPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ectx\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlXPathNewContext\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003exmlXPathObjectPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlXPathEvalExpression\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"//book/title\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ectx\u003c/span\u003e);\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003enodesetval\u003c/span\u003e) {\n    \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003enodesetval\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003enodeNr\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e++\u003c/span\u003e) {\n        \u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003enodesetval\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003enodeTab\u003c/span\u003e[\u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e];\n        \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etext\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e)\u003cspan class=\"pl-en\"\u003exmlNodeGetContent\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enode\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"%s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003etext\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmlFree\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003etext\u003c/span\u003e);\n    }\n}\n\u003cspan class=\"pl-en\"\u003exmlXPathFreeObject\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmlXPathFreeContext\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ectx\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003exmloxide (with compat header):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"xmlNodePtr root = xmlDocGetRootElement(doc);\nxmlXPathObjectPtr result = xmlXPathEval(\u0026quot;//book/title\u0026quot;, root);\nif (result) {\n    int count = xmlXPathNodeSetGetLength(result);\n    for (int i = 0; i \u0026lt; count; i++) {\n        xmlNodePtr node = xmlXPathNodeSetItem(result, i, doc);\n        char *text = xmlNodeGetContent(node);\n        printf(\u0026quot;%s\\n\u0026quot;, text);\n        xmlFree(text);\n        xmlFreeNode(node);\n    }\n}\nxmlXPathFreeObject(result);\nxmlFreeNode(root);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlDocGetRootElement\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003exmlXPathObjectPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlXPathEval\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"//book/title\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e);\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e) {\n    \u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecount\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlXPathNodeSetGetLength\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e);\n    \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ecount\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e++\u003c/span\u003e) {\n        \u003cspan class=\"pl-smi\"\u003exmlNodePtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enode\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlXPathNodeSetItem\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n        \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003etext\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlNodeGetContent\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enode\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"%s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003etext\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmlFree\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003etext\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmlFreeNode\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003enode\u003c/span\u003e);\n    }\n}\n\u003cspan class=\"pl-en\"\u003exmlXPathFreeObject\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmlFreeNode\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eroot\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eKey changes:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNo \u003ccode\u003exmlXPathContext\u003c/code\u003e needed — pass the context node directly\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003exmlXPathNodeSetItem()\u003c/code\u003e takes the document pointer as an extra argument\u003c/li\u003e\n\u003cli\u003eNode handles from XPath results must be freed\u003c/li\u003e\n\u003cli\u003eAttribute-axis results are attribute nodes: \u003ccode\u003exmloxide_xpath_nodeset_item()\u003c/code\u003e\nreturns the owner element's id for them, and\n\u003ccode\u003exmloxide_xpath_nodeset_item_is_attribute()\u003c/code\u003e /\n\u003ccode\u003exmloxide_xpath_nodeset_item_attr_name()\u003c/code\u003e /\n\u003ccode\u003exmloxide_xpath_nodeset_item_attr_value()\u003c/code\u003e expose the attribute itself\n(libxml2 instead returns an \u003ccode\u003eXML_ATTRIBUTE_NODE\u003c/code\u003e from\n\u003ccode\u003exmlXPathNodeSetItem\u003c/code\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eError handling\u003c/h3\u003e\u003ca id=\"user-content-error-handling\" class=\"anchor\" aria-label=\"Permalink: Error handling\" href=\"#error-handling\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003elibxml2:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"xmlSetGenericErrorFunc(NULL, my_error_handler);\nxmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);\nif (!doc) {\n    xmlErrorPtr err = xmlGetLastError();\n    fprintf(stderr, \u0026quot;Error at %d:%d: %s\\n\u0026quot;, err-\u0026gt;line, err-\u0026gt;int2, err-\u0026gt;message);\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003exmlSetGenericErrorFunc\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003emy_error_handler\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlReadMemory\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ebuf\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003esize\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e);\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (!\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e) {\n    \u003cspan class=\"pl-smi\"\u003exmlErrorPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eerr\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlGetLastError\u003c/span\u003e();\n    \u003cspan class=\"pl-en\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003estderr\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\"Error at %d:%d: %s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eerr\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eline\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eerr\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eint2\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eerr\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003emessage\u003c/span\u003e);\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003exmloxide:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);\nif (!doc) {\n    fprintf(stderr, \u0026quot;Error at %u:%u: %s\\n\u0026quot;,\n            xmloxide_last_error_line(),\n            xmloxide_last_error_column(),\n            xmloxide_last_error());\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlReadMemory\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ebuf\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003esize\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e);\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (!\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e) {\n    \u003cspan class=\"pl-en\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003estderr\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\"Error at %u:%u: %s\\n\"\u003c/span\u003e,\n            \u003cspan class=\"pl-en\"\u003exmloxide_last_error_line\u003c/span\u003e(),\n            \u003cspan class=\"pl-en\"\u003exmloxide_last_error_column\u003c/span\u003e(),\n            \u003cspan class=\"pl-en\"\u003exmloxide_last_error\u003c/span\u003e());\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eKey changes:\u003c/strong\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNo error handler registration (use \u003ccode\u003exmloxide_last_error*()\u003c/code\u003e functions)\u003c/li\u003e\n\u003cli\u003eStructured error info via \u003ccode\u003exmloxide_last_error_line()\u003c/code\u003e / \u003ccode\u003e_column()\u003c/code\u003e / \u003ccode\u003e_severity()\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eFor document diagnostics (recovered errors), use \u003ccode\u003exmloxide_doc_diagnostic_*()\u003c/code\u003e functions\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eHTML5 parsing (new in xmloxide)\u003c/h3\u003e\u003ca id=\"user-content-html5-parsing-new-in-xmloxide\" class=\"anchor\" aria-label=\"Permalink: HTML5 parsing (new in xmloxide)\" href=\"#html5-parsing-new-in-xmloxide\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003elibxml2 ships an HTML 4.01 parser but has no WHATWG HTML5 parser. xmloxide\nimplements the full WHATWG HTML Living Standard tokenizer (section 13.2.5) and tree\nbuilder (section 13.2.6), giving you spec-compliant HTML5 parsing out of the box.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRust:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-rust notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"use xmloxide::html5::{parse_html5, parse_html5_with_options, Html5ParseOptions};\nuse xmloxide::html5::parse_html5_full;\n\n// Full document parsing\nlet doc = parse_html5(\u0026quot;\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;world\u0026lt;/b\u0026gt;\u0026quot;).unwrap();\n\n// Fragment parsing (the innerHTML algorithm)\nlet opts = Html5ParseOptions {\n    scripting: false,\n    fragment_context: Some(\u0026quot;body\u0026quot;.to_string()),\n};\nlet doc = parse_html5_with_options(\u0026quot;\u0026lt;li\u0026gt;Item 1\u0026lt;li\u0026gt;Item 2\u0026quot;, \u0026amp;opts).unwrap();\n\n// Parse and collect all errors (always succeeds — no Result)\nlet result = parse_html5_full(\u0026quot;\u0026lt;p\u0026gt;Hello\u0026lt;/p\u0026gt;\u0026quot;);\nprintln!(\u0026quot;{} parse errors\u0026quot;, result.errors.len());\nlet doc = result.document;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003ehtml5\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003eparse_html5\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e parse_html5_with_options\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eHtml5ParseOptions\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003ehtml5\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003eparse_html5_full\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Full document parsing\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e doc = \u003cspan class=\"pl-en\"\u003eparse_html5\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;world\u0026lt;/b\u0026gt;\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Fragment parsing (the innerHTML algorithm)\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e opts = \u003cspan class=\"pl-smi\"\u003eHtml5ParseOptions\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003escripting\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003efragment_context\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eSome\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"body\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eto_string\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e doc = \u003cspan class=\"pl-en\"\u003eparse_html5_with_options\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"\u0026lt;li\u0026gt;Item 1\u0026lt;li\u0026gt;Item 2\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003eopts\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Parse and collect all errors (always succeeds — no Result)\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e result = \u003cspan class=\"pl-en\"\u003eparse_html5_full\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"\u0026lt;p\u0026gt;Hello\u0026lt;/p\u0026gt;\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eprintln\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"{} parse errors\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e result\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003eerrors\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e doc = result\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003edocument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eC FFI:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#include \u0026quot;xmloxide.h\u0026quot;\n\n/* Full document parsing */\nxmloxide_document *doc = xmloxide_parse_html5(\u0026quot;\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;world\u0026lt;/b\u0026gt;\u0026quot;);\n\n/* Fragment parsing (innerHTML algorithm) */\nxmloxide_document *frag = xmloxide_parse_html5_fragment(\u0026quot;\u0026lt;li\u0026gt;A\u0026lt;li\u0026gt;B\u0026quot;, \u0026quot;ul\u0026quot;);\n\n/* HTML5 serialization */\nchar *html = xmloxide_serialize_html5(doc);\nprintf(\u0026quot;%s\\n\u0026quot;, html);\nxmloxide_free_string(html);\n\nxmloxide_free_doc(frag);\nxmloxide_free_doc(doc);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003e#include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"xmloxide.h\"\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e/* Full document parsing */\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003exmloxide_document\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_parse_html5\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;world\u0026lt;/b\u0026gt;\"\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e/* Fragment parsing (innerHTML algorithm) */\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003exmloxide_document\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003efrag\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_parse_html5_fragment\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"\u0026lt;li\u0026gt;A\u0026lt;li\u0026gt;B\"\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\"ul\"\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e/* HTML5 serialization */\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ehtml\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_serialize_html5\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"%s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ehtml\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmloxide_free_string\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ehtml\u003c/span\u003e);\n\n\u003cspan class=\"pl-en\"\u003exmloxide_free_doc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003efrag\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmloxide_free_doc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eC FFI (with compat header):\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#include \u0026quot;libxml2_compat.h\u0026quot;\n\nxmlDocPtr doc = xmloxide_parse_html5(\u0026quot;\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;world\u0026lt;/b\u0026gt;\u0026quot;);\nxmlDocPtr frag = xmloxide_parse_html5_fragment(\u0026quot;\u0026lt;li\u0026gt;A\u0026lt;li\u0026gt;B\u0026quot;, \u0026quot;ul\u0026quot;);\n\nchar *html = xmloxide_serialize_html5(doc);\nprintf(\u0026quot;%s\\n\u0026quot;, html);\nxmloxide_free_string(html);\n\nxmlFreeDoc(frag);\nxmlFreeDoc(doc);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003e#include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"libxml2_compat.h\"\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_parse_html5\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;world\u0026lt;/b\u0026gt;\"\u003c/span\u003e);\n\u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003efrag\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_parse_html5_fragment\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"\u0026lt;li\u0026gt;A\u0026lt;li\u0026gt;B\"\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\"ul\"\u003c/span\u003e);\n\n\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ehtml\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_serialize_html5\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"%s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ehtml\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmloxide_free_string\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ehtml\u003c/span\u003e);\n\n\u003cspan class=\"pl-en\"\u003exmlFreeDoc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003efrag\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmlFreeDoc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eHTML5 streaming (SAX-like, Rust only)\u003c/h3\u003e\u003ca id=\"user-content-html5-streaming-sax-like-rust-only\" class=\"anchor\" aria-label=\"Permalink: HTML5 streaming (SAX-like, Rust only)\" href=\"#html5-streaming-sax-like-rust-only\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003exmloxide provides a streaming SAX-like API for HTML5 that fires callbacks for\neach token without building a DOM tree. This is useful for large documents\nwhere you only need to extract specific data.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eNote:\u003c/strong\u003e The C FFI SAX interface is XML-only. HTML5 streaming is available\nonly from Rust.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRust:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-rust notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"use xmloxide::html5::sax::{Html5SaxHandler, parse_html5_sax};\n\nstruct LinkExtractor {\n    hrefs: Vec\u0026lt;String\u0026gt;,\n}\n\nimpl Html5SaxHandler for LinkExtractor {\n    fn start_element(\n        \u0026amp;mut self,\n        name: \u0026amp;str,\n        attributes: \u0026amp;[(String, String)],\n        _self_closing: bool,\n    ) {\n        if name == \u0026quot;a\u0026quot; {\n            if let Some((_, href)) = attributes.iter().find(|(n, _)| n == \u0026quot;href\u0026quot;) {\n                self.hrefs.push(href.clone());\n            }\n        }\n    }\n}\n\nlet mut handler = LinkExtractor { hrefs: Vec::new() };\nparse_html5_sax(\n    r#\u0026quot;\u0026lt;a href=\u0026quot;https://example.com\u0026quot;\u0026gt;Link\u0026lt;/a\u0026gt;\u0026lt;a href=\u0026quot;/about\u0026quot;\u0026gt;About\u0026lt;/a\u0026gt;\u0026quot;#,\n    \u0026amp;mut handler,\n);\nassert_eq!(handler.hrefs.len(), 2);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003ehtml5\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003esax\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eHtml5SaxHandler\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e parse_html5_sax\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003estruct\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLinkExtractor\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003ehrefs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eVec\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003eimpl\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eHtml5SaxHandler\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLinkExtractor\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003efn\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estart_element\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\n        \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"pl-k\"\u003emut\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003estr\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003eattributes\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n        \u003cspan class=\"pl-s1\"\u003e_self_closing\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003ebool\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e name == \u003cspan class=\"pl-s\"\u003e\"a\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSome\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e_\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e href\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e = attributes\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eiter\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003efind\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e|\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003en\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e _\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e| n == \u003cspan class=\"pl-s\"\u003e\"href\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n                \u003cspan class=\"pl-smi\"\u003eself\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003ehrefs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003epush\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003ehref\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eclone\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n            \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n        \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e \u003cspan class=\"pl-k\"\u003emut\u003c/span\u003e handler = \u003cspan class=\"pl-smi\"\u003eLinkExtractor\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ehrefs\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e:\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eVec\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enew\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eparse_html5_sax\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003er#\"\u0026lt;a href=\"https://example.com\"\u0026gt;Link\u0026lt;/a\u0026gt;\u0026lt;a href=\"/about\"\u0026gt;About\u0026lt;/a\u0026gt;\"#\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"pl-k\"\u003emut\u003c/span\u003e handler\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert_eq\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003ehandler\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003ehrefs\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e2\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAvailable callbacks on \u003ccode\u003eHtml5SaxHandler\u003c/code\u003e (all have default no-op implementations):\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003estart_element(name, attributes, self_closing)\u003c/code\u003e — start tags\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eend_element(name)\u003c/code\u003e — end tags\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003echaracters(content)\u003c/code\u003e — text content (coalesced)\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecomment(content)\u003c/code\u003e — HTML comments\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003edoctype(name, public_id, system_id)\u003c/code\u003e — DOCTYPE declarations\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eerror(error)\u003c/code\u003e — tokenizer errors\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSchematron validation (new in xmloxide)\u003c/h3\u003e\u003ca id=\"user-content-schematron-validation-new-in-xmloxide\" class=\"anchor\" aria-label=\"Permalink: Schematron validation (new in xmloxide)\" href=\"#schematron-validation-new-in-xmloxide\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003elibxml2 has limited Schematron support (only basic assert/report). xmloxide\nimplements ISO Schematron (ISO/IEC 19757-3) with phases, abstract patterns,\nand \u003ccode\u003eis-a\u003c/code\u003e instantiation.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRust:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-rust notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"use xmloxide::Document;\nuse xmloxide::validation::schematron::{\n    parse_schematron, validate_schematron, validate_schematron_with_phase,\n};\n\n// Parse the Schematron schema\nlet schema = parse_schematron(r#\u0026quot;\n  \u0026lt;schema xmlns=\u0026quot;http://purl.oclc.org/dml/schematron\u0026quot;\u0026gt;\n    \u0026lt;phase id=\u0026quot;quick\u0026quot;\u0026gt;\n      \u0026lt;active pattern=\u0026quot;structure\u0026quot;/\u0026gt;\n    \u0026lt;/phase\u0026gt;\n    \u0026lt;pattern id=\u0026quot;structure\u0026quot;\u0026gt;\n      \u0026lt;rule context=\u0026quot;/order\u0026quot;\u0026gt;\n        \u0026lt;assert test=\u0026quot;@id\u0026quot;\u0026gt;Order must have an id attribute\u0026lt;/assert\u0026gt;\n        \u0026lt;assert test=\u0026quot;item\u0026quot;\u0026gt;Order must contain at least one item\u0026lt;/assert\u0026gt;\n      \u0026lt;/rule\u0026gt;\n    \u0026lt;/pattern\u0026gt;\n    \u0026lt;pattern id=\u0026quot;business-rules\u0026quot;\u0026gt;\n      \u0026lt;rule context=\u0026quot;/order/item\u0026quot;\u0026gt;\n        \u0026lt;assert test=\u0026quot;@price \u0026gt; 0\u0026quot;\u0026gt;Price must be positive\u0026lt;/assert\u0026gt;\n      \u0026lt;/rule\u0026gt;\n    \u0026lt;/pattern\u0026gt;\n  \u0026lt;/schema\u0026gt;\n\u0026quot;#).unwrap();\n\nlet doc = Document::parse_str(r#\u0026quot;\u0026lt;order id=\u0026quot;123\u0026quot;\u0026gt;\u0026lt;item price=\u0026quot;10\u0026quot;/\u0026gt;\u0026lt;/order\u0026gt;\u0026quot;#).unwrap();\n\n// Validate against all patterns\nlet result = validate_schematron(\u0026amp;doc, \u0026amp;schema);\nassert!(result.is_valid);\n\n// Validate against a specific phase (only \u0026quot;structure\u0026quot; patterns)\nlet result = validate_schematron_with_phase(\u0026amp;doc, \u0026amp;schema, \u0026quot;quick\u0026quot;);\nassert!(result.is_valid);\n\n// Inspect validation errors\nif !result.is_valid {\n    for error in \u0026amp;result.errors {\n        eprintln!(\u0026quot;{}:{} {}\u0026quot;, error.line.unwrap_or(0), error.column.unwrap_or(0), error.message);\n    }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eDocument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003evalidation\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003eschematron\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    parse_schematron\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e validate_schematron\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e validate_schematron_with_phase\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Parse the Schematron schema\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e schema = \u003cspan class=\"pl-en\"\u003eparse_schematron\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003er#\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e  \u0026lt;schema xmlns=\"http://purl.oclc.org/dml/schematron\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;phase id=\"quick\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;active pattern=\"structure\"/\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;/phase\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;pattern id=\"structure\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;rule context=\"/order\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        \u0026lt;assert test=\"@id\"\u0026gt;Order must have an id attribute\u0026lt;/assert\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        \u0026lt;assert test=\"item\"\u0026gt;Order must contain at least one item\u0026lt;/assert\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;/rule\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;/pattern\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;pattern id=\"business-rules\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;rule context=\"/order/item\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        \u0026lt;assert test=\"@price \u0026gt; 0\"\u0026gt;Price must be positive\u0026lt;/assert\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;/rule\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;/pattern\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e  \u0026lt;/schema\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\"#\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e doc = \u003cspan class=\"pl-smi\"\u003eDocument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eparse_str\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003er#\"\u0026lt;order id=\"123\"\u0026gt;\u0026lt;item price=\"10\"/\u0026gt;\u0026lt;/order\u0026gt;\"#\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Validate against all patterns\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e result = \u003cspan class=\"pl-en\"\u003evalidate_schematron\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003eschema\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eresult\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003eis_valid\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Validate against a specific phase (only \"structure\" patterns)\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e result = \u003cspan class=\"pl-en\"\u003evalidate_schematron_with_phase\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003eschema\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"quick\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eresult\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003eis_valid\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Inspect validation errors\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e !result\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eis_valid\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e error \u003cspan class=\"pl-k\"\u003ein\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003eresult\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eerrors\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n        \u003cspan class=\"pl-en\"\u003eeprintln\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"{}:{} {}\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e error\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003eline\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003eunwrap_or\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e error\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003ecolumn\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003eunwrap_or\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e error\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003emessage\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eC FFI:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#include \u0026quot;xmloxide.h\u0026quot;\n\nconst char *schema_xml = \u0026quot;\u0026lt;schema xmlns='http://purl.oclc.org/dml/schematron'\u0026gt;\u0026quot;\n    \u0026quot;\u0026lt;pattern id='p1'\u0026gt;\u0026quot;\n    \u0026quot;  \u0026lt;rule context='/order'\u0026gt;\u0026quot;\n    \u0026quot;    \u0026lt;assert test='@id'\u0026gt;Order must have an id\u0026lt;/assert\u0026gt;\u0026quot;\n    \u0026quot;  \u0026lt;/rule\u0026gt;\u0026quot;\n    \u0026quot;\u0026lt;/pattern\u0026gt;\u0026quot;\n    \u0026quot;\u0026lt;/schema\u0026gt;\u0026quot;;\n\n/* Parse schema */\nxmloxide_schematron_schema *schema = xmloxide_parse_schematron(schema_xml);\n\n/* Parse document */\nxmloxide_document *doc = xmloxide_parse(\u0026quot;\u0026lt;order id='1'\u0026gt;\u0026lt;item/\u0026gt;\u0026lt;/order\u0026gt;\u0026quot;);\n\n/* Validate (all patterns) */\nxmloxide_validation_result *result = xmloxide_validate_schematron(doc, schema);\nif (xmloxide_validation_is_valid(result)) {\n    printf(\u0026quot;Valid!\\n\u0026quot;);\n} else {\n    size_t n = xmloxide_validation_error_count(result);\n    for (size_t i = 0; i \u0026lt; n; i++) {\n        char *msg = xmloxide_validation_error_message(result, i);\n        printf(\u0026quot;Error: %s\\n\u0026quot;, msg);\n        xmloxide_free_string(msg);\n    }\n}\nxmloxide_free_validation_result(result);\n\n/* Validate with a specific phase */\nresult = xmloxide_validate_schematron_with_phase(doc, schema, \u0026quot;quick\u0026quot;);\nxmloxide_free_validation_result(result);\n\nxmloxide_free_schematron(schema);\nxmloxide_free_doc(doc);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003e#include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"xmloxide.h\"\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003econst\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eschema_xml\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"\u0026lt;schema xmlns='http://purl.oclc.org/dml/schematron'\u0026gt;\"\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"\u0026lt;pattern id='p1'\u0026gt;\"\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"  \u0026lt;rule context='/order'\u0026gt;\"\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"    \u0026lt;assert test='@id'\u0026gt;Order must have an id\u0026lt;/assert\u0026gt;\"\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"  \u0026lt;/rule\u0026gt;\"\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"\u0026lt;/pattern\u0026gt;\"\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"\u0026lt;/schema\u0026gt;\"\u003c/span\u003e;\n\n\u003cspan class=\"pl-c\"\u003e/* Parse schema */\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003exmloxide_schematron_schema\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eschema\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_parse_schematron\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eschema_xml\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e/* Parse document */\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003exmloxide_document\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_parse\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"\u0026lt;order id='1'\u0026gt;\u0026lt;item/\u0026gt;\u0026lt;/order\u0026gt;\"\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e/* Validate (all patterns) */\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003exmloxide_validation_result\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_validate_schematron\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eschema\u003c/span\u003e);\n\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-en\"\u003exmloxide_validation_is_valid\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e)) {\n    \u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"Valid!\\n\"\u003c/span\u003e);\n} \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e {\n    \u003cspan class=\"pl-smi\"\u003esize_t\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_validation_error_count\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e);\n    \u003cspan class=\"pl-k\"\u003efor\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003esize_t\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e; \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e++\u003c/span\u003e) {\n        \u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003emsg\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_validation_error_message\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003ei\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"Error: %s\\n\"\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003emsg\u003c/span\u003e);\n        \u003cspan class=\"pl-en\"\u003exmloxide_free_string\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003emsg\u003c/span\u003e);\n    }\n}\n\u003cspan class=\"pl-en\"\u003exmloxide_free_validation_result\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e/* Validate with a specific phase */\u003c/span\u003e\n\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmloxide_validate_schematron_with_phase\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eschema\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\"quick\"\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmloxide_free_validation_result\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eresult\u003c/span\u003e);\n\n\u003cspan class=\"pl-en\"\u003exmloxide_free_schematron\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eschema\u003c/span\u003e);\n\u003cspan class=\"pl-en\"\u003exmloxide_free_doc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003edoc\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCSS selectors (new in xmloxide, Rust only)\u003c/h3\u003e\u003ca id=\"user-content-css-selectors-new-in-xmloxide-rust-only\" class=\"anchor\" aria-label=\"Permalink: CSS selectors (new in xmloxide, Rust only)\" href=\"#css-selectors-new-in-xmloxide-rust-only\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003elibxml2 has no CSS selector API — it uses XPath exclusively. xmloxide provides\na \u003ccode\u003ecss::select\u003c/code\u003e function that supports a broad set of CSS selectors as an\nalternative to XPath for element queries.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRust:\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-rust notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"use xmloxide::css::select;\nuse xmloxide::Document;\n\nlet doc = Document::parse_str(r#\u0026quot;\n    \u0026lt;html\u0026gt;\n      \u0026lt;body\u0026gt;\n        \u0026lt;div class=\u0026quot;content\u0026quot;\u0026gt;\n          \u0026lt;p id=\u0026quot;intro\u0026quot;\u0026gt;Hello\u0026lt;/p\u0026gt;\n          \u0026lt;p class=\u0026quot;highlight\u0026quot;\u0026gt;World\u0026lt;/p\u0026gt;\n          \u0026lt;ul\u0026gt;\n            \u0026lt;li class=\u0026quot;active\u0026quot;\u0026gt;One\u0026lt;/li\u0026gt;\n            \u0026lt;li\u0026gt;Two\u0026lt;/li\u0026gt;\n          \u0026lt;/ul\u0026gt;\n        \u0026lt;/div\u0026gt;\n      \u0026lt;/body\u0026gt;\n    \u0026lt;/html\u0026gt;\n\u0026quot;#).unwrap();\n\nlet root = doc.root_element().unwrap();\n\n// Tag selector\nlet paragraphs = select(\u0026amp;doc, root, \u0026quot;p\u0026quot;).unwrap();\nassert_eq!(paragraphs.len(), 2);\n\n// Class selector\nlet highlighted = select(\u0026amp;doc, root, \u0026quot;.highlight\u0026quot;).unwrap();\nassert_eq!(highlighted.len(), 1);\n\n// ID selector\nlet intro = select(\u0026amp;doc, root, \u0026quot;#intro\u0026quot;).unwrap();\nassert_eq!(intro.len(), 1);\n\n// Combinators and pseudo-classes\nlet first_li = select(\u0026amp;doc, root, \u0026quot;ul \u0026gt; li:first-child\u0026quot;).unwrap();\nassert_eq!(first_li.len(), 1);\n\n// Attribute selectors\nlet active = select(\u0026amp;doc, root, \u0026quot;[class~='active']\u0026quot;).unwrap();\nassert_eq!(active.len(), 1);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003ecss\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003eselect\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e xmloxide\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-v\"\u003eDocument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e doc = \u003cspan class=\"pl-smi\"\u003eDocument\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e::\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eparse_str\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s\"\u003er#\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;html\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;body\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        \u0026lt;div class=\"content\"\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          \u0026lt;p id=\"intro\"\u0026gt;Hello\u0026lt;/p\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          \u0026lt;p class=\"highlight\"\u0026gt;World\u0026lt;/p\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          \u0026lt;ul\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026lt;li class=\"active\"\u0026gt;One\u0026lt;/li\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e            \u0026lt;li\u0026gt;Two\u0026lt;/li\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e          \u0026lt;/ul\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e        \u0026lt;/div\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e      \u0026lt;/body\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e    \u0026lt;/html\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e\"#\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e root = doc\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eroot_element\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Tag selector\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e paragraphs = \u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e root\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"p\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert_eq\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eparagraphs\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e2\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Class selector\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e highlighted = \u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e root\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\".highlight\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert_eq\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003ehighlighted\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// ID selector\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e intro = \u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e root\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"#intro\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert_eq\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eintro\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Combinators and pseudo-classes\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e first_li = \u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e root\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"ul \u0026gt; li:first-child\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert_eq\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003efirst_li\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e// Attribute selectors\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003elet\u003c/span\u003e active = \u003cspan class=\"pl-en\"\u003eselect\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e\u0026amp;\u003c/span\u003edoc\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e root\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"[class~='active']\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003eassert_eq\u003c/span\u003e\u003cspan class=\"pl-en\"\u003e!\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003eactive\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003elen\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e1\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSupported selectors include: tag, \u003ccode\u003e.class\u003c/code\u003e, \u003ccode\u003e#id\u003c/code\u003e, \u003ccode\u003e*\u003c/code\u003e, \u003ccode\u003e[attr]\u003c/code\u003e,\n\u003ccode\u003e[attr=\"value\"]\u003c/code\u003e, \u003ccode\u003e[attr^=]\u003c/code\u003e, \u003ccode\u003e[attr$=]\u003c/code\u003e, \u003ccode\u003e[attr*=]\u003c/code\u003e, \u003ccode\u003e[attr~=]\u003c/code\u003e,\n\u003ccode\u003e[attr|=]\u003c/code\u003e, descendant (space), child (\u003ccode\u003e\u0026gt;\u003c/code\u003e), adjacent (\u003ccode\u003e+\u003c/code\u003e), general\nsibling (\u003ccode\u003e~\u003c/code\u003e), grouping (\u003ccode\u003e,\u003c/code\u003e), \u003ccode\u003e:first-child\u003c/code\u003e, \u003ccode\u003e:last-child\u003c/code\u003e, \u003ccode\u003e:only-child\u003c/code\u003e,\n\u003ccode\u003e:empty\u003c/code\u003e, \u003ccode\u003e:not()\u003c/code\u003e, and \u003ccode\u003e:nth-child()\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eWhat's NOT compatible\u003c/h2\u003e\u003ca id=\"user-content-whats-not-compatible\" class=\"anchor\" aria-label=\"Permalink: What's NOT compatible\" href=\"#whats-not-compatible\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThese libxml2 patterns require code changes and cannot be papered over:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eDirect struct member access\u003c/strong\u003e — \u003ccode\u003enode-\u0026gt;name\u003c/code\u003e, \u003ccode\u003enode-\u0026gt;type\u003c/code\u003e, \u003ccode\u003enode-\u0026gt;children\u003c/code\u003e, \u003ccode\u003enode-\u0026gt;ns\u003c/code\u003e. Use accessor functions instead.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ePointer-based iteration\u003c/strong\u003e — \u003ccode\u003efor (cur = node-\u0026gt;children; cur; cur = cur-\u0026gt;next)\u003c/code\u003e. Use \u003ccode\u003exmlNodeGetChildren()\u003c/code\u003e + \u003ccode\u003exmlNodeGetNext()\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCustom error handlers\u003c/strong\u003e — \u003ccode\u003exmlSetGenericErrorFunc()\u003c/code\u003e. Use \u003ccode\u003exmloxide_last_error*()\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eParser context manipulation\u003c/strong\u003e — \u003ccode\u003exmlNewParserCtxt()\u003c/code\u003e, \u003ccode\u003exmlCtxtReadMemory()\u003c/code\u003e. Use the simpler parse functions directly.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eCustom entity loaders\u003c/strong\u003e — \u003ccode\u003exmlSetExternalEntityLoader()\u003c/code\u003e. Not exposed.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eXSLT\u003c/strong\u003e — Out of scope (separate library in both libxml2 and xmloxide).\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eThread safety\u003c/h2\u003e\u003ca id=\"user-content-thread-safety\" class=\"anchor\" aria-label=\"Permalink: Thread safety\" href=\"#thread-safety\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUnlike libxml2, xmloxide requires \u003cstrong\u003eno synchronization\u003c/strong\u003e for independent documents. Each \u003ccode\u003exmlDocPtr\u003c/code\u003e is fully self-contained. The only shared state is the per-thread error message (\u003ccode\u003exmloxide_last_error()\u003c/code\u003e), which uses thread-local storage.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/* Safe: different threads, different documents */\n/* Thread 1 */ xmlDocPtr doc1 = xmlParseDoc(xml1);\n/* Thread 2 */ xmlDocPtr doc2 = xmlParseDoc(xml2);\n\n/* NOT safe: same document from multiple threads without synchronization */\n/* Use a mutex if you need to share a document across threads */\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/* Safe: different threads, different documents */\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e/* Thread 1 */\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc1\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlParseDoc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003exml1\u003c/span\u003e);\n\u003cspan class=\"pl-c\"\u003e/* Thread 2 */\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003exmlDocPtr\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edoc2\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003exmlParseDoc\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003exml2\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e/* NOT safe: same document from multiple threads without synchronization */\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e/* Use a mutex if you need to share a document across threads */\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"Migrating from libxml2 to xmloxide","fully_qualified_name":"Migrating from libxml2 to xmloxide","kind":"section_1","ident_start":2,"ident_end":36,"extent_start":0,"extent_end":13805,"ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":36}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":437,"utf16_col":0}}},{"name":"Quick start","fully_qualified_name":"Quick start","kind":"section_2","ident_start":120,"ident_end":131,"extent_start":117,"extent_end":433,"ident_utf16":{"start":{"line_number":4,"utf16_col":3},"end":{"line_number":4,"utf16_col":14}},"extent_utf16":{"start":{"line_number":4,"utf16_col":0},"end":{"line_number":11,"utf16_col":0}}},{"name":"Key differences","fully_qualified_name":"Key differences","kind":"section_2","ident_start":436,"ident_end":451,"extent_start":433,"extent_end":1108,"ident_utf16":{"start":{"line_number":11,"utf16_col":3},"end":{"line_number":11,"utf16_col":18}},"extent_utf16":{"start":{"line_number":11,"utf16_col":0},"end":{"line_number":23,"utf16_col":0}}},{"name":"Before and after","fully_qualified_name":"Before and after","kind":"section_2","ident_start":1111,"ident_end":1127,"extent_start":1108,"extent_end":12504,"ident_utf16":{"start":{"line_number":23,"utf16_col":3},"end":{"line_number":23,"utf16_col":19}},"extent_utf16":{"start":{"line_number":23,"utf16_col":0},"end":{"line_number":414,"utf16_col":0}}},{"name":"Parsing and inspecting a document","fully_qualified_name":"Parsing and inspecting a document","kind":"section_3","ident_start":1133,"ident_end":1166,"extent_start":1129,"extent_end":2747,"ident_utf16":{"start":{"line_number":25,"utf16_col":4},"end":{"line_number":25,"utf16_col":37}},"extent_utf16":{"start":{"line_number":25,"utf16_col":0},"end":{"line_number":83,"utf16_col":0}}},{"name":"XPath queries","fully_qualified_name":"XPath queries","kind":"section_3","ident_start":2751,"ident_end":2764,"extent_start":2747,"extent_end":4311,"ident_utf16":{"start":{"line_number":83,"utf16_col":4},"end":{"line_number":83,"utf16_col":17}},"extent_utf16":{"start":{"line_number":83,"utf16_col":0},"end":{"line_number":131,"utf16_col":0}}},{"name":"Error handling","fully_qualified_name":"Error handling","kind":"section_3","ident_start":4315,"ident_end":4329,"extent_start":4311,"extent_end":5121,"ident_utf16":{"start":{"line_number":131,"utf16_col":4},"end":{"line_number":131,"utf16_col":18}},"extent_utf16":{"start":{"line_number":131,"utf16_col":0},"end":{"line_number":159,"utf16_col":0}}},{"name":"HTML5 parsing (new in xmloxide)","fully_qualified_name":"HTML5 parsing (new in xmloxide)","kind":"section_3","ident_start":5125,"ident_end":5156,"extent_start":5121,"extent_end":6813,"ident_utf16":{"start":{"line_number":159,"utf16_col":4},"end":{"line_number":159,"utf16_col":35}},"extent_utf16":{"start":{"line_number":159,"utf16_col":0},"end":{"line_number":220,"utf16_col":0}}},{"name":"HTML5 streaming (SAX-like, Rust only)","fully_qualified_name":"HTML5 streaming (SAX-like, Rust only)","kind":"section_3","ident_start":6817,"ident_end":6854,"extent_start":6813,"extent_end":8237,"ident_utf16":{"start":{"line_number":220,"utf16_col":4},"end":{"line_number":220,"utf16_col":41}},"extent_utf16":{"start":{"line_number":220,"utf16_col":0},"end":{"line_number":268,"utf16_col":0}}},{"name":"Schematron validation (new in xmloxide)","fully_qualified_name":"Schematron validation (new in xmloxide)","kind":"section_3","ident_start":8241,"ident_end":8280,"extent_start":8237,"extent_end":10950,"ident_utf16":{"start":{"line_number":268,"utf16_col":4},"end":{"line_number":268,"utf16_col":43}},"extent_utf16":{"start":{"line_number":268,"utf16_col":0},"end":{"line_number":359,"utf16_col":0}}},{"name":"CSS selectors (new in xmloxide, Rust only)","fully_qualified_name":"CSS selectors (new in xmloxide, Rust only)","kind":"section_3","ident_start":10954,"ident_end":10996,"extent_start":10950,"extent_end":12504,"ident_utf16":{"start":{"line_number":359,"utf16_col":4},"end":{"line_number":359,"utf16_col":46}},"extent_utf16":{"start":{"line_number":359,"utf16_col":0},"end":{"line_number":414,"utf16_col":0}}},{"name":"What's NOT compatible","fully_qualified_name":"What's NOT compatible","kind":"section_2","ident_start":12507,"ident_end":12528,"extent_start":12504,"extent_end":13242,"ident_utf16":{"start":{"line_number":414,"utf16_col":3},"end":{"line_number":414,"utf16_col":24}},"extent_utf16":{"start":{"line_number":414,"utf16_col":0},"end":{"line_number":425,"utf16_col":0}}},{"name":"Thread safety","fully_qualified_name":"Thread safety","kind":"section_2","ident_start":13245,"ident_end":13258,"extent_start":13242,"extent_end":13805,"ident_utf16":{"start":{"line_number":425,"utf16_col":3},"end":{"line_number":425,"utf16_col":16}},"extent_utf16":{"start":{"line_number":425,"utf16_col":0},"end":{"line_number":437,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":1163839325,"defaultBranch":"main","name":"xmloxide","ownerLogin":"jonwiggins","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2026-02-22T08:22:18.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/35540058?v=4","public":true,"private":false,"isOrgOwned":false,"isArchived":false},"currentUser":null,"uploadToken":"lOhlRPg4YnlVoD8Bz8ENvWs4VUamLvSwDtrx-kz1rxHy_rQx9jkG-0kYC9fxIJbaVtv91OI8E1pHlSlqojp6Gw","allShortcutsEnabled":false,"treeExpanded":true,"path":"MIGRATION.md","symbolsExpanded":false,"refInfo":{"name":"main","listCacheKey":"v0:1791411856.0","canEdit":false,"currentOid":"555055f1ea6bf9944488fd96415b6f03b5b43696"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"":{"items":[{"name":".claude","path":".claude","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":"benches","path":"benches","contentType":"directory"},{"name":"examples","path":"examples","contentType":"directory"},{"name":"fuzz","path":"fuzz","contentType":"directory"},{"name":"include","path":"include","contentType":"directory"},{"name":"pyxmloxide","path":"pyxmloxide","contentType":"directory"},{"name":"scripts","path":"scripts","contentType":"directory"},{"name":"src","path":"src","contentType":"directory"},{"name":"tests","path":"tests","contentType":"directory"},{"name":"xmloxide-wasm","path":"xmloxide-wasm","contentType":"directory"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"CHANGELOG.md","path":"CHANGELOG.md","contentType":"file"},{"name":"CLAUDE.md","path":"CLAUDE.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"Cargo.lock","path":"Cargo.lock","contentType":"file"},{"name":"Cargo.toml","path":"Cargo.toml","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"MIGRATION.md","path":"MIGRATION.md","contentType":"file"},{"name":"Makefile","path":"Makefile","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"clippy.toml","path":"clippy.toml","contentType":"file"},{"name":"rustfmt.toml","path":"rustfmt.toml","contentType":"file"}],"totalCount":23}},"fileTreeProcessingTime":18.753162,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"main","listCacheKey":"v0:1791411856.0","canEdit":false,"refType":"branch","currentOid":"555055f1ea6bf9944488fd96415b6f03b5b43696","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"MIGRATION.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/jonwiggins/xmloxide/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"MIGRATION.md","displayUrl":"https://github.com/jonwiggins/xmloxide/blob/main/MIGRATION.md?raw=true","headerInfo":{"blobSize":"13.5 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"c619ff8","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fjonwiggins%2Fxmloxide%2Fblob%2Fmain%2FMIGRATION.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"437","truncatedSloc":"359"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/jonwiggins/xmloxide/blob/main/MIGRATION.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/jonwiggins/xmloxide/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/jonwiggins/xmloxide/raw/refs/heads/main/MIGRATION.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["# Migrating from libxml2 to xmloxide","","This guide covers how to migrate C/C++ code from libxml2 to xmloxide's C FFI.","","## Quick start","","1. Replace `#include \u003clibxml/parser.h\u003e` (etc.) with `#include \"libxml2_compat.h\"`","2. Remove `xmlInitParser()` / `xmlCleanupParser()` calls (they become no-ops)","3. Replace direct struct member access (`node-\u003ename`) with accessor functions","4. Build and link against `libxmloxide` instead of `libxml2`","","## Key differences","","| Concept | libxml2 | xmloxide |","|---------|---------|----------|","| Node access | Dereference pointer: `node-\u003ename` | Call function: `xmlNodeGetName(node)` |","| Navigation | Pointer chain: `node-\u003eparent-\u003echildren` | Function calls: `xmlNodeGetParent(node)` |","| Node identity | Raw pointer (`xmlNodePtr`) | Handle struct with `(doc, id)` pair |","| Global state | Required: `xmlInitParser()` | None needed |","| Thread safety | Manual synchronization | Automatic (`Send + Sync`) |","| Error handling | Global/context error handler | Thread-local: `xmloxide_last_error()` |","| String deallocation | `xmlFree()` | `xmlFree()` (compat) or `xmloxide_free_string()` |","","## Before and after","","### Parsing and inspecting a document","","**libxml2:**","```c","#include \u003clibxml/parser.h\u003e","#include \u003clibxml/tree.h\u003e","","xmlInitParser();","xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);","xmlNodePtr root = xmlDocGetRootElement(doc);","printf(\"Root: %s\\n\", root-\u003ename);","","for (xmlNodePtr cur = root-\u003echildren; cur; cur = cur-\u003enext) {","    if (cur-\u003etype == XML_ELEMENT_NODE) {","        char *content = (char *)xmlNodeGetContent(cur);","        printf(\"  %s: %s\\n\", cur-\u003ename, content);","        xmlFree(content);","    }","}","xmlFreeDoc(doc);","xmlCleanupParser();","```","","**xmloxide (with compat header):**","```c","#include \"libxml2_compat.h\"","","xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);","xmlNodePtr root = xmlDocGetRootElement(doc);","char *root_name = xmlNodeGetName(root);","printf(\"Root: %s\\n\", root_name);","xmlFree(root_name);","","xmlNodePtr cur = xmlNodeGetChildren(root);","while (cur) {","    if (xmlNodeGetType(cur) == XMLOXIDE_NODE_ELEMENT) {","        char *name = xmlNodeGetName(cur);","        char *content = xmlNodeGetContent(cur);","        printf(\"  %s: %s\\n\", name, content);","        xmlFree(name);","        xmlFree(content);","    }","    xmlNodePtr next = xmlNodeGetNext(cur);","    xmlFreeNode(cur);","    cur = next;","}","xmlFreeNode(root);","xmlFreeDoc(doc);","```","","**Key changes:**","- No `xmlInitParser()` / `xmlCleanupParser()`","- `root-\u003ename` becomes `xmlNodeGetName(root)` (returns owned string)","- `root-\u003echildren` becomes `xmlNodeGetChildren(root)` (returns handle)","- `cur-\u003enext` becomes `xmlNodeGetNext(cur)`","- Node handles must be freed with `xmlFreeNode()` when done","- Strings from accessor functions are always owned and must be freed","","### XPath queries","","**libxml2:**","```c","xmlXPathContextPtr ctx = xmlXPathNewContext(doc);","xmlXPathObjectPtr result = xmlXPathEvalExpression(\"//book/title\", ctx);","if (result \u0026\u0026 result-\u003enodesetval) {","    for (int i = 0; i \u003c result-\u003enodesetval-\u003enodeNr; i++) {","        xmlNodePtr node = result-\u003enodesetval-\u003enodeTab[i];","        char *text = (char *)xmlNodeGetContent(node);","        printf(\"%s\\n\", text);","        xmlFree(text);","    }","}","xmlXPathFreeObject(result);","xmlXPathFreeContext(ctx);","```","","**xmloxide (with compat header):**","```c","xmlNodePtr root = xmlDocGetRootElement(doc);","xmlXPathObjectPtr result = xmlXPathEval(\"//book/title\", root);","if (result) {","    int count = xmlXPathNodeSetGetLength(result);","    for (int i = 0; i \u003c count; i++) {","        xmlNodePtr node = xmlXPathNodeSetItem(result, i, doc);","        char *text = xmlNodeGetContent(node);","        printf(\"%s\\n\", text);","        xmlFree(text);","        xmlFreeNode(node);","    }","}","xmlXPathFreeObject(result);","xmlFreeNode(root);","```","","**Key changes:**","- No `xmlXPathContext` needed — pass the context node directly","- `xmlXPathNodeSetItem()` takes the document pointer as an extra argument","- Node handles from XPath results must be freed","- Attribute-axis results are attribute nodes: `xmloxide_xpath_nodeset_item()`","  returns the owner element's id for them, and","  `xmloxide_xpath_nodeset_item_is_attribute()` /","  `xmloxide_xpath_nodeset_item_attr_name()` /","  `xmloxide_xpath_nodeset_item_attr_value()` expose the attribute itself","  (libxml2 instead returns an `XML_ATTRIBUTE_NODE` from","  `xmlXPathNodeSetItem`)","","### Error handling","","**libxml2:**","```c","xmlSetGenericErrorFunc(NULL, my_error_handler);","xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);","if (!doc) {","    xmlErrorPtr err = xmlGetLastError();","    fprintf(stderr, \"Error at %d:%d: %s\\n\", err-\u003eline, err-\u003eint2, err-\u003emessage);","}","```","","**xmloxide:**","```c","xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);","if (!doc) {","    fprintf(stderr, \"Error at %u:%u: %s\\n\",","            xmloxide_last_error_line(),","            xmloxide_last_error_column(),","            xmloxide_last_error());","}","```","","**Key changes:**","- No error handler registration (use `xmloxide_last_error*()` functions)","- Structured error info via `xmloxide_last_error_line()` / `_column()` / `_severity()`","- For document diagnostics (recovered errors), use `xmloxide_doc_diagnostic_*()` functions","","### HTML5 parsing (new in xmloxide)","","libxml2 ships an HTML 4.01 parser but has no WHATWG HTML5 parser. xmloxide","implements the full WHATWG HTML Living Standard tokenizer (section 13.2.5) and tree","builder (section 13.2.6), giving you spec-compliant HTML5 parsing out of the box.","","**Rust:**","```rust","use xmloxide::html5::{parse_html5, parse_html5_with_options, Html5ParseOptions};","use xmloxide::html5::parse_html5_full;","","// Full document parsing","let doc = parse_html5(\"\u003cp\u003eHello \u003cb\u003eworld\u003c/b\u003e\").unwrap();","","// Fragment parsing (the innerHTML algorithm)","let opts = Html5ParseOptions {","    scripting: false,","    fragment_context: Some(\"body\".to_string()),","};","let doc = parse_html5_with_options(\"\u003cli\u003eItem 1\u003cli\u003eItem 2\", \u0026opts).unwrap();","","// Parse and collect all errors (always succeeds — no Result)","let result = parse_html5_full(\"\u003cp\u003eHello\u003c/p\u003e\");","println!(\"{} parse errors\", result.errors.len());","let doc = result.document;","```","","**C FFI:**","```c","#include \"xmloxide.h\"","","/* Full document parsing */","xmloxide_document *doc = xmloxide_parse_html5(\"\u003cp\u003eHello \u003cb\u003eworld\u003c/b\u003e\");","","/* Fragment parsing (innerHTML algorithm) */","xmloxide_document *frag = xmloxide_parse_html5_fragment(\"\u003cli\u003eA\u003cli\u003eB\", \"ul\");","","/* HTML5 serialization */","char *html = xmloxide_serialize_html5(doc);","printf(\"%s\\n\", html);","xmloxide_free_string(html);","","xmloxide_free_doc(frag);","xmloxide_free_doc(doc);","```","","**C FFI (with compat header):**","```c","#include \"libxml2_compat.h\"","","xmlDocPtr doc = xmloxide_parse_html5(\"\u003cp\u003eHello \u003cb\u003eworld\u003c/b\u003e\");","xmlDocPtr frag = xmloxide_parse_html5_fragment(\"\u003cli\u003eA\u003cli\u003eB\", \"ul\");","","char *html = xmloxide_serialize_html5(doc);","printf(\"%s\\n\", html);","xmloxide_free_string(html);","","xmlFreeDoc(frag);","xmlFreeDoc(doc);","```","","### HTML5 streaming (SAX-like, Rust only)","","xmloxide provides a streaming SAX-like API for HTML5 that fires callbacks for","each token without building a DOM tree. This is useful for large documents","where you only need to extract specific data.","","**Note:** The C FFI SAX interface is XML-only. HTML5 streaming is available","only from Rust.","","**Rust:**","```rust","use xmloxide::html5::sax::{Html5SaxHandler, parse_html5_sax};","","struct LinkExtractor {","    hrefs: Vec\u003cString\u003e,","}","","impl Html5SaxHandler for LinkExtractor {","    fn start_element(","        \u0026mut self,","        name: \u0026str,","        attributes: \u0026[(String, String)],","        _self_closing: bool,","    ) {","        if name == \"a\" {","            if let Some((_, href)) = attributes.iter().find(|(n, _)| n == \"href\") {","                self.hrefs.push(href.clone());","            }","        }","    }","}","","let mut handler = LinkExtractor { hrefs: Vec::new() };","parse_html5_sax(","    r#\"\u003ca href=\"https://example.com\"\u003eLink\u003c/a\u003e\u003ca href=\"/about\"\u003eAbout\u003c/a\u003e\"#,","    \u0026mut handler,",");","assert_eq!(handler.hrefs.len(), 2);","```","","Available callbacks on `Html5SaxHandler` (all have default no-op implementations):","- `start_element(name, attributes, self_closing)` — start tags","- `end_element(name)` — end tags","- `characters(content)` — text content (coalesced)","- `comment(content)` — HTML comments","- `doctype(name, public_id, system_id)` — DOCTYPE declarations","- `error(error)` — tokenizer errors","","### Schematron validation (new in xmloxide)","","libxml2 has limited Schematron support (only basic assert/report). xmloxide","implements ISO Schematron (ISO/IEC 19757-3) with phases, abstract patterns,","and `is-a` instantiation.","","**Rust:**","```rust","use xmloxide::Document;","use xmloxide::validation::schematron::{","    parse_schematron, validate_schematron, validate_schematron_with_phase,","};","","// Parse the Schematron schema","let schema = parse_schematron(r#\"","  \u003cschema xmlns=\"http://purl.oclc.org/dml/schematron\"\u003e","    \u003cphase id=\"quick\"\u003e","      \u003cactive pattern=\"structure\"/\u003e","    \u003c/phase\u003e","    \u003cpattern id=\"structure\"\u003e","      \u003crule context=\"/order\"\u003e","        \u003cassert test=\"@id\"\u003eOrder must have an id attribute\u003c/assert\u003e","        \u003cassert test=\"item\"\u003eOrder must contain at least one item\u003c/assert\u003e","      \u003c/rule\u003e","    \u003c/pattern\u003e","    \u003cpattern id=\"business-rules\"\u003e","      \u003crule context=\"/order/item\"\u003e","        \u003cassert test=\"@price \u003e 0\"\u003ePrice must be positive\u003c/assert\u003e","      \u003c/rule\u003e","    \u003c/pattern\u003e","  \u003c/schema\u003e","\"#).unwrap();","","let doc = Document::parse_str(r#\"\u003corder id=\"123\"\u003e\u003citem price=\"10\"/\u003e\u003c/order\u003e\"#).unwrap();","","// Validate against all patterns","let result = validate_schematron(\u0026doc, \u0026schema);","assert!(result.is_valid);","","// Validate against a specific phase (only \"structure\" patterns)","let result = validate_schematron_with_phase(\u0026doc, \u0026schema, \"quick\");","assert!(result.is_valid);","","// Inspect validation errors","if !result.is_valid {","    for error in \u0026result.errors {","        eprintln!(\"{}:{} {}\", error.line.unwrap_or(0), error.column.unwrap_or(0), error.message);","    }","}","```","","**C FFI:**","```c","#include \"xmloxide.h\"","","const char *schema_xml = \"\u003cschema xmlns='http://purl.oclc.org/dml/schematron'\u003e\"","    \"\u003cpattern id='p1'\u003e\"","    \"  \u003crule context='/order'\u003e\"","    \"    \u003cassert test='@id'\u003eOrder must have an id\u003c/assert\u003e\"","    \"  \u003c/rule\u003e\"","    \"\u003c/pattern\u003e\"","    \"\u003c/schema\u003e\";","","/* Parse schema */","xmloxide_schematron_schema *schema = xmloxide_parse_schematron(schema_xml);","","/* Parse document */","xmloxide_document *doc = xmloxide_parse(\"\u003corder id='1'\u003e\u003citem/\u003e\u003c/order\u003e\");","","/* Validate (all patterns) */","xmloxide_validation_result *result = xmloxide_validate_schematron(doc, schema);","if (xmloxide_validation_is_valid(result)) {","    printf(\"Valid!\\n\");","} else {","    size_t n = xmloxide_validation_error_count(result);","    for (size_t i = 0; i \u003c n; i++) {","        char *msg = xmloxide_validation_error_message(result, i);","        printf(\"Error: %s\\n\", msg);","        xmloxide_free_string(msg);","    }","}","xmloxide_free_validation_result(result);","","/* Validate with a specific phase */","result = xmloxide_validate_schematron_with_phase(doc, schema, \"quick\");","xmloxide_free_validation_result(result);","","xmloxide_free_schematron(schema);","xmloxide_free_doc(doc);","```","","### CSS selectors (new in xmloxide, Rust only)","","libxml2 has no CSS selector API — it uses XPath exclusively. xmloxide provides","a `css::select` function that supports a broad set of CSS selectors as an","alternative to XPath for element queries.","","**Rust:**","```rust","use xmloxide::css::select;","use xmloxide::Document;","","let doc = Document::parse_str(r#\"","    \u003chtml\u003e","      \u003cbody\u003e","        \u003cdiv class=\"content\"\u003e","          \u003cp id=\"intro\"\u003eHello\u003c/p\u003e","          \u003cp class=\"highlight\"\u003eWorld\u003c/p\u003e","          \u003cul\u003e","            \u003cli class=\"active\"\u003eOne\u003c/li\u003e","            \u003cli\u003eTwo\u003c/li\u003e","          \u003c/ul\u003e","        \u003c/div\u003e","      \u003c/body\u003e","    \u003c/html\u003e","\"#).unwrap();","","let root = doc.root_element().unwrap();","","// Tag selector","let paragraphs = select(\u0026doc, root, \"p\").unwrap();","assert_eq!(paragraphs.len(), 2);","","// Class selector","let highlighted = select(\u0026doc, root, \".highlight\").unwrap();","assert_eq!(highlighted.len(), 1);","","// ID selector","let intro = select(\u0026doc, root, \"#intro\").unwrap();","assert_eq!(intro.len(), 1);","","// Combinators and pseudo-classes","let first_li = select(\u0026doc, root, \"ul \u003e li:first-child\").unwrap();","assert_eq!(first_li.len(), 1);","","// Attribute selectors","let active = select(\u0026doc, root, \"[class~='active']\").unwrap();","assert_eq!(active.len(), 1);","```","","Supported selectors include: tag, `.class`, `#id`, `*`, `[attr]`,","`[attr=\"value\"]`, `[attr^=]`, `[attr$=]`, `[attr*=]`, `[attr~=]`,","`[attr|=]`, descendant (space), child (`\u003e`), adjacent (`+`), general","sibling (`~`), grouping (`,`), `:first-child`, `:last-child`, `:only-child`,","`:empty`, `:not()`, and `:nth-child()`.","","## What's NOT compatible","","These libxml2 patterns require code changes and cannot be papered over:","","1. **Direct struct member access** — `node-\u003ename`, `node-\u003etype`, `node-\u003echildren`, `node-\u003ens`. Use accessor functions instead.","2. **Pointer-based iteration** — `for (cur = node-\u003echildren; cur; cur = cur-\u003enext)`. Use `xmlNodeGetChildren()` + `xmlNodeGetNext()`.","3. **Custom error handlers** — `xmlSetGenericErrorFunc()`. Use `xmloxide_last_error*()`.","4. **Parser context manipulation** — `xmlNewParserCtxt()`, `xmlCtxtReadMemory()`. Use the simpler parse functions directly.","5. **Custom entity loaders** — `xmlSetExternalEntityLoader()`. Not exposed.","6. **XSLT** — Out of scope (separate library in both libxml2 and xmloxide).","","## Thread safety","","Unlike libxml2, xmloxide requires **no synchronization** for independent documents. Each `xmlDocPtr` is fully self-contained. The only shared state is the per-thread error message (`xmloxide_last_error()`), which uses thread-local storage.","","```c","/* Safe: different threads, different documents */","/* Thread 1 */ xmlDocPtr doc1 = xmlParseDoc(xml1);","/* Thread 2 */ xmlDocPtr doc2 = xmlParseDoc(xml2);","","/* NOT safe: same document from multiple threads without synchronization */","/* Use a mutex if you need to share a document across threads */","```"],"stylingDirectives":[[[0,36,"pl-mh"],[2,36,"pl-en"]],[],[],[],[[0,14,"pl-mh"],[3,14,"pl-en"]],[],[[0,1,"pl-s"],[1,2,"pl-v"],[11,12,"pl-s"],[12,38,"pl-c1"],[38,39,"pl-s"],[52,53,"pl-s"],[53,80,"pl-c1"],[80,81,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[10,11,"pl-s"],[11,26,"pl-c1"],[26,27,"pl-s"],[30,31,"pl-s"],[31,49,"pl-c1"],[49,50,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[40,41,"pl-s"],[41,51,"pl-c1"],[51,52,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[26,27,"pl-s"],[27,38,"pl-c1"],[38,39,"pl-s"],[51,52,"pl-s"],[52,59,"pl-c1"],[59,60,"pl-s"]],[],[[0,18,"pl-mh"],[3,18,"pl-en"]],[],[[0,1,"pl-ml"],[10,11,"pl-ml"],[20,21,"pl-ml"],[31,32,"pl-ml"]],[[0,1,"pl-ml"],[10,11,"pl-ml"],[20,21,"pl-ml"],[31,32,"pl-ml"]],[[0,1,"pl-ml"],[14,15,"pl-ml"],[37,38,"pl-s"],[38,48,"pl-c1"],[48,49,"pl-s"],[50,51,"pl-ml"],[67,68,"pl-s"],[68,88,"pl-c1"],[88,89,"pl-s"],[90,91,"pl-ml"]],[[0,1,"pl-ml"],[13,14,"pl-ml"],[30,31,"pl-s"],[31,53,"pl-c1"],[53,54,"pl-s"],[55,56,"pl-ml"],[73,74,"pl-s"],[74,96,"pl-c1"],[96,97,"pl-s"],[98,99,"pl-ml"]],[[0,1,"pl-ml"],[16,17,"pl-ml"],[31,32,"pl-s"],[32,42,"pl-c1"],[42,43,"pl-s"],[45,46,"pl-ml"],[66,67,"pl-s"],[67,76,"pl-c1"],[76,77,"pl-s"],[83,84,"pl-ml"]],[[0,1,"pl-ml"],[15,16,"pl-ml"],[27,28,"pl-s"],[28,43,"pl-c1"],[43,44,"pl-s"],[45,46,"pl-ml"],[59,60,"pl-ml"]],[[0,1,"pl-ml"],[16,17,"pl-ml"],[41,42,"pl-ml"],[54,55,"pl-s"],[55,66,"pl-c1"],[66,67,"pl-s"],[69,70,"pl-ml"]],[[0,1,"pl-ml"],[17,18,"pl-ml"],[48,49,"pl-ml"],[64,65,"pl-s"],[65,86,"pl-c1"],[86,87,"pl-s"],[88,89,"pl-ml"]],[[0,1,"pl-ml"],[22,23,"pl-ml"],[24,25,"pl-s"],[25,34,"pl-c1"],[34,35,"pl-s"],[36,37,"pl-ml"],[38,39,"pl-s"],[39,48,"pl-c1"],[48,49,"pl-s"],[62,63,"pl-s"],[63,85,"pl-c1"],[85,86,"pl-s"],[87,88,"pl-ml"]],[],[[0,19,"pl-mh"],[3,19,"pl-en"]],[],[[0,37,"pl-mh"],[4,37,"pl-en"]],[],[[0,2,"pl-s"],[10,12,"pl-s"]],[[0,3,"pl-s"],[3,4,"pl-en"]],[[1,8,"pl-k"],[9,26,"pl-s"],[9,10,"pl-pds"],[25,26,"pl-pds"]],[[1,8,"pl-k"],[9,24,"pl-s"],[9,10,"pl-pds"],[23,24,"pl-pds"]],[],[[0,13,"pl-en"]],[[41,45,"pl-c1"],[47,51,"pl-c1"],[53,54,"pl-c1"]],[],[[0,6,"pl-en"]],[],[],[],[[13,14,"pl-s"],[30,31,"pl-s"]],[],[],[],[],[],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,0,"pl-c1"]],[[0,34,"pl-c1"]],[[0,4,"pl-c1"]],[[0,27,"pl-c1"]],[[0,0,"pl-c1"]],[[0,56,"pl-c1"]],[[0,44,"pl-c1"]],[[0,39,"pl-c1"]],[[0,32,"pl-c1"]],[[0,19,"pl-c1"]],[[0,0,"pl-c1"]],[[0,42,"pl-c1"]],[[0,13,"pl-c1"]],[[0,55,"pl-c1"]],[[0,41,"pl-c1"]],[[0,47,"pl-c1"]],[[0,44,"pl-c1"]],[[0,22,"pl-c1"]],[[0,25,"pl-c1"]],[[0,5,"pl-c1"]],[[0,42,"pl-c1"]],[[0,21,"pl-c1"]],[[0,15,"pl-c1"]],[[0,1,"pl-c1"]],[[0,18,"pl-c1"]],[[0,16,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,2,"pl-s"],[14,16,"pl-s"]],[[0,1,"pl-v"],[5,6,"pl-s"],[6,21,"pl-c1"],[21,22,"pl-s"],[25,26,"pl-s"],[26,44,"pl-c1"],[44,45,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,13,"pl-c1"],[13,14,"pl-s"],[23,24,"pl-s"],[24,44,"pl-c1"],[44,45,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,17,"pl-c1"],[17,18,"pl-s"],[27,28,"pl-s"],[28,52,"pl-c1"],[52,53,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,12,"pl-c1"],[12,13,"pl-s"],[22,23,"pl-s"],[23,42,"pl-c1"],[42,43,"pl-s"]],[[0,1,"pl-v"],[34,35,"pl-s"],[35,48,"pl-c1"],[48,49,"pl-s"]],[[0,1,"pl-v"]],[],[[0,17,"pl-mh"],[4,17,"pl-en"]],[],[[0,2,"pl-s"],[10,12,"pl-s"]],[[0,3,"pl-s"],[3,4,"pl-en"]],[],[[50,64,"pl-s"],[50,51,"pl-pds"],[63,64,"pl-pds"]],[[0,2,"pl-k"]],[[4,58,"pl-c1"]],[[4,57,"pl-c1"]],[[4,53,"pl-c1"]],[[8,14,"pl-c1"]],[],[],[],[[0,18,"pl-en"]],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,0,"pl-c1"]],[[0,34,"pl-c1"]],[[0,4,"pl-c1"]],[[0,44,"pl-c1"]],[[0,62,"pl-c1"]],[[0,13,"pl-c1"]],[[0,49,"pl-c1"]],[[0,37,"pl-c1"]],[[0,62,"pl-c1"]],[[0,45,"pl-c1"]],[[0,29,"pl-c1"]],[[0,22,"pl-c1"]],[[0,26,"pl-c1"]],[[0,5,"pl-c1"]],[[0,1,"pl-c1"]],[[0,27,"pl-c1"]],[[0,18,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,2,"pl-s"],[14,16,"pl-s"]],[[0,1,"pl-v"],[5,6,"pl-s"],[6,21,"pl-c1"],[21,22,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,24,"pl-c1"],[24,25,"pl-s"]],[[0,1,"pl-v"]],[[0,1,"pl-v"],[46,47,"pl-s"],[47,76,"pl-c1"],[76,77,"pl-s"]],[],[[2,3,"pl-s"],[3,45,"pl-c1"],[45,46,"pl-s"]],[[2,3,"pl-s"],[3,42,"pl-c1"],[42,43,"pl-s"]],[[2,3,"pl-s"],[3,43,"pl-c1"],[43,44,"pl-s"]],[[30,31,"pl-s"],[31,49,"pl-c1"],[49,50,"pl-s"]],[[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[],[[0,18,"pl-mh"],[4,18,"pl-en"]],[],[[0,2,"pl-s"],[10,12,"pl-s"]],[[0,3,"pl-s"],[3,4,"pl-en"]],[[0,22,"pl-en"]],[],[],[],[],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,0,"pl-c1"]],[[0,13,"pl-c1"]],[[0,4,"pl-c1"]],[[0,56,"pl-c1"]],[[0,11,"pl-c1"]],[[0,43,"pl-c1"]],[[0,39,"pl-c1"]],[[0,41,"pl-c1"]],[[0,35,"pl-c1"]],[[0,1,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,2,"pl-s"],[14,16,"pl-s"]],[[0,1,"pl-v"],[37,38,"pl-s"],[38,60,"pl-c1"],[60,61,"pl-s"]],[[0,1,"pl-v"],[28,29,"pl-s"],[29,55,"pl-c1"],[55,56,"pl-s"],[59,60,"pl-s"],[60,69,"pl-c1"],[69,70,"pl-s"],[73,74,"pl-s"],[74,85,"pl-c1"],[85,86,"pl-s"]],[[0,1,"pl-v"],[51,52,"pl-s"],[52,79,"pl-c1"],[79,80,"pl-s"]],[],[[0,35,"pl-mh"],[4,35,"pl-en"]],[],[],[],[],[],[[0,2,"pl-s"],[7,9,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,3,"pl-k"],[4,12,"pl-en"],[12,14,"pl-k"],[14,19,"pl-en"],[19,21,"pl-k"],[61,78,"pl-en"]],[[0,3,"pl-k"],[4,12,"pl-en"],[12,14,"pl-k"],[14,19,"pl-en"],[19,21,"pl-k"]],[],[[0,24,"pl-c"],[0,2,"pl-c"]],[[0,3,"pl-k"],[4,7,"pl-smi"],[8,9,"pl-k"],[10,21,"pl-en"],[22,45,"pl-s"],[22,23,"pl-pds"],[44,45,"pl-pds"],[46,47,"pl-k"],[47,53,"pl-en"]],[],[[0,45,"pl-c"],[0,2,"pl-c"]],[[0,3,"pl-k"],[4,8,"pl-smi"],[9,10,"pl-k"],[11,28,"pl-en"]],[[4,13,"pl-smi"],[13,14,"pl-k"],[15,20,"pl-c1"]],[[4,20,"pl-smi"],[20,21,"pl-k"],[22,26,"pl-en"],[27,33,"pl-s"],[27,28,"pl-pds"],[32,33,"pl-pds"],[33,34,"pl-k"],[34,43,"pl-en"]],[],[[0,3,"pl-k"],[4,7,"pl-smi"],[8,9,"pl-k"],[10,34,"pl-en"],[35,57,"pl-s"],[35,36,"pl-pds"],[56,57,"pl-pds"],[59,60,"pl-k"],[60,64,"pl-smi"],[65,66,"pl-k"],[66,72,"pl-en"]],[],[[0,61,"pl-c"],[0,2,"pl-c"]],[[0,3,"pl-k"],[4,10,"pl-smi"],[11,12,"pl-k"],[13,29,"pl-en"],[30,44,"pl-s"],[30,31,"pl-pds"],[43,44,"pl-pds"]],[[0,8,"pl-en"],[9,26,"pl-s"],[9,10,"pl-pds"],[25,26,"pl-pds"],[28,34,"pl-smi"],[34,35,"pl-k"],[41,42,"pl-k"],[42,45,"pl-en"]],[[0,3,"pl-k"],[4,7,"pl-smi"],[8,9,"pl-k"],[10,16,"pl-smi"],[16,17,"pl-k"]],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[8,10,"pl-s"]],[[0,3,"pl-s"],[3,4,"pl-en"]],[[1,8,"pl-k"],[9,21,"pl-s"],[9,10,"pl-pds"],[20,21,"pl-pds"]],[],[[0,27,"pl-c"],[0,2,"pl-c"],[25,27,"pl-c"]],[[46,69,"pl-s"],[46,47,"pl-pds"],[68,69,"pl-pds"]],[],[[0,44,"pl-c"],[0,2,"pl-c"],[42,44,"pl-c"]],[[56,68,"pl-s"],[56,57,"pl-pds"],[67,68,"pl-pds"],[70,74,"pl-s"],[70,71,"pl-pds"],[73,74,"pl-pds"]],[],[[0,25,"pl-c"],[0,2,"pl-c"],[23,25,"pl-c"]],[[0,4,"pl-k"]],[[0,6,"pl-en"]],[],[],[],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,0,"pl-c1"]],[[0,31,"pl-c1"]],[[0,4,"pl-c1"]],[[0,27,"pl-c1"]],[[0,0,"pl-c1"]],[[0,62,"pl-c1"]],[[0,67,"pl-c1"]],[[0,0,"pl-c1"]],[[0,43,"pl-c1"]],[[0,21,"pl-c1"]],[[0,27,"pl-c1"]],[[0,0,"pl-c1"]],[[0,17,"pl-c1"]],[[0,16,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[0,41,"pl-mh"],[4,41,"pl-en"]],[],[],[],[],[],[[0,2,"pl-s"],[7,9,"pl-s"]],[],[],[[0,2,"pl-s"],[7,9,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,3,"pl-k"],[4,12,"pl-en"],[12,14,"pl-k"],[14,19,"pl-en"],[19,21,"pl-k"],[21,24,"pl-en"],[24,26,"pl-k"],[27,42,"pl-en"]],[],[[0,6,"pl-k"],[7,20,"pl-en"]],[[4,9,"pl-smi"],[9,10,"pl-k"],[11,14,"pl-en"],[15,21,"pl-en"]],[],[],[[0,4,"pl-k"],[5,20,"pl-en"],[21,24,"pl-k"],[25,38,"pl-en"]],[[4,6,"pl-k"],[7,20,"pl-en"]],[[8,9,"pl-k"],[9,12,"pl-k"],[13,17,"pl-c1"]],[[8,12,"pl-smi"],[12,13,"pl-k"],[14,15,"pl-k"],[15,18,"pl-k"]],[[8,18,"pl-smi"],[18,19,"pl-k"],[20,21,"pl-k"],[23,29,"pl-en"],[31,37,"pl-en"]],[[8,21,"pl-smi"],[21,22,"pl-k"],[23,27,"pl-k"]],[],[[8,10,"pl-k"],[11,15,"pl-smi"],[16,18,"pl-k"],[19,22,"pl-s"],[19,20,"pl-pds"],[21,22,"pl-pds"]],[[12,14,"pl-k"],[15,18,"pl-k"],[19,23,"pl-en"],[25,26,"pl-smi"],[28,32,"pl-smi"],[35,36,"pl-k"],[37,47,"pl-smi"],[47,48,"pl-k"],[48,52,"pl-en"],[54,55,"pl-k"],[55,59,"pl-en"],[60,61,"pl-k"],[62,63,"pl-smi"],[65,66,"pl-smi"],[67,68,"pl-k"],[69,70,"pl-smi"],[71,73,"pl-k"],[74,80,"pl-s"],[74,75,"pl-pds"],[79,80,"pl-pds"]],[[16,20,"pl-c1"],[20,21,"pl-k"],[26,27,"pl-k"],[27,31,"pl-en"],[32,36,"pl-smi"],[36,37,"pl-k"],[37,42,"pl-en"]],[],[],[],[],[],[[0,3,"pl-k"],[4,7,"pl-k"],[8,15,"pl-smi"],[16,17,"pl-k"],[18,31,"pl-en"],[34,39,"pl-smi"],[39,40,"pl-k"],[41,44,"pl-en"],[44,46,"pl-k"],[46,49,"pl-en"]],[[0,15,"pl-en"]],[[4,73,"pl-s"],[4,5,"pl-s"],[5,6,"pl-pds"],[6,7,"pl-pds"],[71,72,"pl-pds"],[72,73,"pl-pds"]],[[4,5,"pl-k"],[5,8,"pl-k"],[9,16,"pl-smi"]],[],[[0,10,"pl-en"],[11,18,"pl-smi"],[18,19,"pl-k"],[24,25,"pl-k"],[25,28,"pl-en"],[32,33,"pl-c1"]],[[0,3,"pl-s"]],[],[[23,24,"pl-s"],[24,39,"pl-c1"],[39,40,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,48,"pl-c1"],[48,49,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,20,"pl-c1"],[20,21,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,22,"pl-c1"],[22,23,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,19,"pl-c1"],[19,20,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,38,"pl-c1"],[38,39,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[3,15,"pl-c1"],[15,16,"pl-s"]],[],[[0,43,"pl-mh"],[4,43,"pl-en"]],[],[],[],[[4,5,"pl-s"],[5,9,"pl-c1"],[9,10,"pl-s"]],[],[[0,2,"pl-s"],[7,9,"pl-s"]],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,3,"pl-k"],[4,12,"pl-en"],[12,14,"pl-k"],[14,22,"pl-en"]],[[0,3,"pl-k"],[4,12,"pl-en"],[12,14,"pl-k"],[14,24,"pl-en"],[24,26,"pl-k"],[26,36,"pl-en"],[36,38,"pl-k"]],[],[],[],[[0,30,"pl-c"],[0,2,"pl-c"]],[[0,3,"pl-k"],[4,10,"pl-smi"],[11,12,"pl-k"],[13,29,"pl-en"],[30,33,"pl-s"],[30,31,"pl-s"],[31,32,"pl-pds"],[32,33,"pl-pds"]],[[0,54,"pl-s"]],[[0,22,"pl-s"]],[[0,35,"pl-s"]],[[0,12,"pl-s"]],[[0,28,"pl-s"]],[[0,29,"pl-s"]],[[0,67,"pl-s"]],[[0,73,"pl-s"]],[[0,13,"pl-s"]],[[0,14,"pl-s"]],[[0,33,"pl-s"]],[[0,34,"pl-s"]],[[0,65,"pl-s"]],[[0,13,"pl-s"]],[[0,14,"pl-s"]],[[0,11,"pl-s"]],[[0,2,"pl-s"],[0,1,"pl-pds"],[1,2,"pl-pds"],[3,4,"pl-k"],[4,10,"pl-en"]],[],[[0,3,"pl-k"],[4,7,"pl-smi"],[8,9,"pl-k"],[10,18,"pl-en"],[18,20,"pl-k"],[20,29,"pl-en"],[30,77,"pl-s"],[30,31,"pl-s"],[31,32,"pl-pds"],[32,33,"pl-pds"],[75,76,"pl-pds"],[76,77,"pl-pds"],[78,79,"pl-k"],[79,85,"pl-en"]],[],[[0,32,"pl-c"],[0,2,"pl-c"]],[[0,3,"pl-k"],[4,10,"pl-smi"],[11,12,"pl-k"],[13,32,"pl-en"],[33,34,"pl-k"],[34,37,"pl-smi"],[39,40,"pl-k"],[40,46,"pl-smi"]],[[0,7,"pl-en"],[8,14,"pl-smi"],[14,15,"pl-k"]],[],[[0,64,"pl-c"],[0,2,"pl-c"]],[[0,3,"pl-k"],[4,10,"pl-smi"],[11,12,"pl-k"],[13,43,"pl-en"],[44,45,"pl-k"],[45,48,"pl-smi"],[50,51,"pl-k"],[51,57,"pl-smi"],[59,66,"pl-s"],[59,60,"pl-pds"],[65,66,"pl-pds"]],[[0,7,"pl-en"],[8,14,"pl-smi"],[14,15,"pl-k"]],[],[[0,28,"pl-c"],[0,2,"pl-c"]],[[0,2,"pl-k"],[3,4,"pl-k"],[4,10,"pl-smi"],[10,11,"pl-k"]],[[4,7,"pl-k"],[8,13,"pl-smi"],[14,16,"pl-k"],[17,18,"pl-k"],[18,24,"pl-smi"],[24,25,"pl-k"]],[[8,17,"pl-en"],[18,28,"pl-s"],[18,19,"pl-pds"],[27,28,"pl-pds"],[30,35,"pl-smi"],[35,36,"pl-k"],[40,41,"pl-k"],[41,50,"pl-en"],[51,52,"pl-c1"],[55,60,"pl-smi"],[60,61,"pl-k"],[67,68,"pl-k"],[68,77,"pl-en"],[78,79,"pl-c1"],[82,87,"pl-smi"],[87,88,"pl-k"]],[],[],[[0,3,"pl-s"]],[],[[0,2,"pl-s"],[8,10,"pl-s"]],[[0,3,"pl-s"],[3,4,"pl-en"]],[[1,8,"pl-k"],[9,21,"pl-s"],[9,10,"pl-pds"],[20,21,"pl-pds"]],[],[[0,5,"pl-k"],[6,10,"pl-k"],[25,79,"pl-s"],[25,26,"pl-pds"],[78,79,"pl-pds"]],[[4,23,"pl-s"],[4,5,"pl-pds"],[22,23,"pl-pds"]],[[4,31,"pl-s"],[4,5,"pl-pds"],[30,31,"pl-pds"]],[[4,59,"pl-s"],[4,5,"pl-pds"],[58,59,"pl-pds"]],[[4,15,"pl-s"],[4,5,"pl-pds"],[14,15,"pl-pds"]],[[4,16,"pl-s"],[4,5,"pl-pds"],[15,16,"pl-pds"]],[[4,15,"pl-s"],[4,5,"pl-pds"],[14,15,"pl-pds"]],[],[[0,18,"pl-c"],[0,2,"pl-c"],[16,18,"pl-c"]],[],[],[[0,20,"pl-c"],[0,2,"pl-c"],[18,20,"pl-c"]],[[40,71,"pl-s"],[40,41,"pl-pds"],[70,71,"pl-pds"]],[],[[0,29,"pl-c"],[0,2,"pl-c"],[27,29,"pl-c"]],[],[[0,2,"pl-k"]],[[4,10,"pl-c1"]],[[2,6,"pl-k"]],[[4,55,"pl-c1"]],[[4,36,"pl-c1"]],[[4,65,"pl-c1"]],[[8,14,"pl-c1"]],[],[],[],[[0,31,"pl-en"]],[],[[1,2,"pl-s"],[34,35,"pl-s"]],[],[],[],[],[],[[0,3,"pl-s"],[3,3,"pl-c1"]],[[0,0,"pl-c1"]],[[0,46,"pl-c1"]],[[0,0,"pl-c1"]],[[0,78,"pl-c1"]],[[0,73,"pl-c1"]],[[0,41,"pl-c1"]],[[0,0,"pl-c1"]],[[0,9,"pl-c1"]],[[0,7,"pl-c1"]],[[0,26,"pl-c1"]],[[0,23,"pl-c1"]],[[0,0,"pl-c1"]],[[0,33,"pl-c1"]],[[0,10,"pl-c1"]],[[0,12,"pl-c1"]],[[0,29,"pl-c1"]],[[0,33,"pl-c1"]],[[0,40,"pl-c1"]],[[0,14,"pl-c1"]],[[0,39,"pl-c1"]],[[0,24,"pl-c1"]],[[0,15,"pl-c1"]],[[0,14,"pl-c1"]],[[0,13,"pl-c1"]],[[0,11,"pl-c1"]],[[0,13,"pl-c1"]],[[0,0,"pl-c1"]],[[0,39,"pl-c1"]],[[0,0,"pl-c1"]],[[0,15,"pl-c1"]],[[0,50,"pl-c1"]],[[0,32,"pl-c1"]],[[0,0,"pl-c1"]],[[0,17,"pl-c1"]],[[0,60,"pl-c1"]],[[0,33,"pl-c1"]],[[0,0,"pl-c1"]],[[0,14,"pl-c1"]],[[0,50,"pl-c1"]],[[0,27,"pl-c1"]],[[0,0,"pl-c1"]],[[0,33,"pl-c1"]],[[0,66,"pl-c1"]],[[0,30,"pl-c1"]],[[0,0,"pl-c1"]],[[0,22,"pl-c1"]],[[0,62,"pl-c1"]],[[0,28,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[34,35,"pl-s"],[35,41,"pl-c1"],[41,42,"pl-s"],[44,45,"pl-s"],[45,48,"pl-c1"],[48,49,"pl-s"],[51,52,"pl-s"],[52,53,"pl-c1"],[53,54,"pl-s"],[56,57,"pl-s"],[57,63,"pl-c1"],[63,64,"pl-s"]],[[0,1,"pl-s"],[1,15,"pl-c1"],[15,16,"pl-s"],[18,19,"pl-s"],[19,27,"pl-c1"],[27,28,"pl-s"],[30,31,"pl-s"],[31,39,"pl-c1"],[39,40,"pl-s"],[42,43,"pl-s"],[43,51,"pl-c1"],[51,52,"pl-s"],[54,55,"pl-s"],[55,63,"pl-c1"],[63,64,"pl-s"]],[[0,1,"pl-s"],[1,9,"pl-c1"],[9,10,"pl-s"],[39,40,"pl-s"],[40,41,"pl-c1"],[41,42,"pl-s"],[55,56,"pl-s"],[56,57,"pl-c1"],[57,58,"pl-s"]],[[9,10,"pl-s"],[10,11,"pl-c1"],[11,12,"pl-s"],[25,26,"pl-s"],[26,27,"pl-c1"],[27,28,"pl-s"],[31,32,"pl-s"],[32,44,"pl-c1"],[44,45,"pl-s"],[47,48,"pl-s"],[48,59,"pl-c1"],[59,60,"pl-s"],[62,63,"pl-s"],[63,74,"pl-c1"],[74,75,"pl-s"]],[[0,1,"pl-s"],[1,7,"pl-c1"],[7,8,"pl-s"],[10,11,"pl-s"],[11,17,"pl-c1"],[17,18,"pl-s"],[24,25,"pl-s"],[25,37,"pl-c1"],[37,38,"pl-s"]],[],[[0,24,"pl-mh"],[3,24,"pl-en"]],[],[],[],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[32,34,"pl-s"],[37,38,"pl-s"],[38,48,"pl-c1"],[48,49,"pl-s"],[51,52,"pl-s"],[52,62,"pl-c1"],[62,63,"pl-s"],[65,66,"pl-s"],[66,80,"pl-c1"],[80,81,"pl-s"],[83,84,"pl-s"],[84,92,"pl-c1"],[92,93,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[28,30,"pl-s"],[33,34,"pl-s"],[34,82,"pl-c1"],[82,83,"pl-s"],[89,90,"pl-s"],[90,110,"pl-c1"],[110,111,"pl-s"],[114,115,"pl-s"],[115,131,"pl-c1"],[131,132,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[26,28,"pl-s"],[31,32,"pl-s"],[32,56,"pl-c1"],[56,57,"pl-s"],[63,64,"pl-s"],[64,86,"pl-c1"],[86,87,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[32,34,"pl-s"],[37,38,"pl-s"],[38,56,"pl-c1"],[56,57,"pl-s"],[59,60,"pl-s"],[60,79,"pl-c1"],[79,80,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[26,28,"pl-s"],[31,32,"pl-s"],[32,60,"pl-c1"],[60,61,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,5,"pl-s"],[9,11,"pl-s"]],[],[[0,16,"pl-mh"],[3,16,"pl-en"]],[],[[34,36,"pl-s"],[54,56,"pl-s"],[89,90,"pl-s"],[90,99,"pl-c1"],[99,100,"pl-s"],[181,182,"pl-s"],[182,203,"pl-c1"],[203,204,"pl-s"]],[],[[0,3,"pl-s"],[3,4,"pl-en"]],[[0,50,"pl-c"],[0,2,"pl-c"],[48,50,"pl-c"]],[[0,14,"pl-c"],[0,2,"pl-c"],[12,14,"pl-c"]],[[0,14,"pl-c"],[0,2,"pl-c"],[12,14,"pl-c"]],[],[[0,75,"pl-c"],[0,2,"pl-c"],[73,75,"pl-c"]],[[0,64,"pl-c"],[0,2,"pl-c"],[62,64,"pl-c"]],[[0,3,"pl-s"]]],"colorizedLines":null}},"title":"xmloxide/MIGRATION.md at main · jonwiggins/xmloxide","appPayload":{},"meta":{"title":"xmloxide/MIGRATION.md at main · jonwiggins/xmloxide"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/jonwiggins/xmloxide" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/jonwiggins/xmloxide/tree/main" data-discover="true">xmloxide</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">MIGRATION.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_1cpla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_1cpla9lik5_ _R_1cpla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_1cpla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7p9la9lik5_" id="_R_99la9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7p9la9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_7pdla9lik5_" id="_R_9dla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_7pdla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/jonwiggins/xmloxide/commits/main/MIGRATION.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/jonwiggins/xmloxide/commits/main/MIGRATION.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="13.5 KB" style="--truncate-max-width:100%"><span>437 lines (359 loc) · 13.5 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/jonwiggins/xmloxide/tree/main" data-discover="true">xmloxide</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">MIGRATION.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="13.5 KB" style="--truncate-max-width:100%"><span>437 lines (359 loc) · 13.5 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/jonwiggins/xmloxide/raw/refs/heads/main/MIGRATION.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Migrating from libxml2 to xmloxide</h1><a id="user-content-migrating-from-libxml2-to-xmloxide" class="anchor" aria-label="Permalink: Migrating from libxml2 to xmloxide" href="#migrating-from-libxml2-to-xmloxide"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This guide covers how to migrate C/C++ code from libxml2 to xmloxide's C FFI.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Quick start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick start" href="#quick-start"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>Replace <code>#include &lt;libxml/parser.h&gt;</code> (etc.) with <code>#include "libxml2_compat.h"</code></li>
<li>Remove <code>xmlInitParser()</code> / <code>xmlCleanupParser()</code> calls (they become no-ops)</li>
<li>Replace direct struct member access (<code>node-&gt;name</code>) with accessor functions</li>
<li>Build and link against <code>libxmloxide</code> instead of <code>libxml2</code></li>
</ol>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Key differences</h2><a id="user-content-key-differences" class="anchor" aria-label="Permalink: Key differences" href="#key-differences"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Concept</th>
<th>libxml2</th>
<th>xmloxide</th>
</tr>
</thead>
<tbody>
<tr>
<td>Node access</td>
<td>Dereference pointer: <code>node-&gt;name</code></td>
<td>Call function: <code>xmlNodeGetName(node)</code></td>
</tr>
<tr>
<td>Navigation</td>
<td>Pointer chain: <code>node-&gt;parent-&gt;children</code></td>
<td>Function calls: <code>xmlNodeGetParent(node)</code></td>
</tr>
<tr>
<td>Node identity</td>
<td>Raw pointer (<code>xmlNodePtr</code>)</td>
<td>Handle struct with <code>(doc, id)</code> pair</td>
</tr>
<tr>
<td>Global state</td>
<td>Required: <code>xmlInitParser()</code></td>
<td>None needed</td>
</tr>
<tr>
<td>Thread safety</td>
<td>Manual synchronization</td>
<td>Automatic (<code>Send + Sync</code>)</td>
</tr>
<tr>
<td>Error handling</td>
<td>Global/context error handler</td>
<td>Thread-local: <code>xmloxide_last_error()</code></td>
</tr>
<tr>
<td>String deallocation</td>
<td><code>xmlFree()</code></td>
<td><code>xmlFree()</code> (compat) or <code>xmloxide_free_string()</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Before and after</h2><a id="user-content-before-and-after" class="anchor" aria-label="Permalink: Before and after" href="#before-and-after"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Parsing and inspecting a document</h3><a id="user-content-parsing-and-inspecting-a-document" class="anchor" aria-label="Permalink: Parsing and inspecting a document" href="#parsing-and-inspecting-a-document"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>libxml2:</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &lt;libxml/parser.h&gt;
#include &lt;libxml/tree.h&gt;

xmlInitParser();
xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);
xmlNodePtr root = xmlDocGetRootElement(doc);
printf(&quot;Root: %s\n&quot;, root-&gt;name);

for (xmlNodePtr cur = root-&gt;children; cur; cur = cur-&gt;next) {
    if (cur-&gt;type == XML_ELEMENT_NODE) {
        char *content = (char *)xmlNodeGetContent(cur);
        printf(&quot;  %s: %s\n&quot;, cur-&gt;name, content);
        xmlFree(content);
    }
}
xmlFreeDoc(doc);
xmlCleanupParser();"><pre><span class="pl-k">#include</span> <span class="pl-s">&lt;libxml/parser.h&gt;</span>
<span class="pl-k">#include</span> <span class="pl-s">&lt;libxml/tree.h&gt;</span>

<span class="pl-en">xmlInitParser</span>();
<span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmlReadMemory</span>(<span class="pl-s1">buf</span>, <span class="pl-s1">size</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">0</span>);
<span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">root</span> <span class="pl-c1">=</span> <span class="pl-en">xmlDocGetRootElement</span>(<span class="pl-s1">doc</span>);
<span class="pl-en">printf</span>(<span class="pl-s">"Root: %s\n"</span>, <span class="pl-s1">root</span><span class="pl-c1">-&gt;</span><span class="pl-c1">name</span>);

<span class="pl-k">for</span> (<span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">cur</span> <span class="pl-c1">=</span> <span class="pl-s1">root</span><span class="pl-c1">-&gt;</span><span class="pl-c1">children</span>; <span class="pl-s1">cur</span>; <span class="pl-s1">cur</span> <span class="pl-c1">=</span> <span class="pl-s1">cur</span><span class="pl-c1">-&gt;</span><span class="pl-c1">next</span>) {
    <span class="pl-k">if</span> (<span class="pl-s1">cur</span><span class="pl-c1">-&gt;</span><span class="pl-c1">type</span> <span class="pl-c1">==</span> <span class="pl-c1">XML_ELEMENT_NODE</span>) {
        <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">content</span> <span class="pl-c1">=</span> (<span class="pl-smi">char</span> <span class="pl-c1">*</span>)<span class="pl-en">xmlNodeGetContent</span>(<span class="pl-s1">cur</span>);
        <span class="pl-en">printf</span>(<span class="pl-s">"  %s: %s\n"</span>, <span class="pl-s1">cur</span><span class="pl-c1">-&gt;</span><span class="pl-c1">name</span>, <span class="pl-s1">content</span>);
        <span class="pl-en">xmlFree</span>(<span class="pl-s1">content</span>);
    }
}
<span class="pl-en">xmlFreeDoc</span>(<span class="pl-s1">doc</span>);
<span class="pl-en">xmlCleanupParser</span>();</pre></div>
<p dir="auto"><strong>xmloxide (with compat header):</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &quot;libxml2_compat.h&quot;

xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);
xmlNodePtr root = xmlDocGetRootElement(doc);
char *root_name = xmlNodeGetName(root);
printf(&quot;Root: %s\n&quot;, root_name);
xmlFree(root_name);

xmlNodePtr cur = xmlNodeGetChildren(root);
while (cur) {
    if (xmlNodeGetType(cur) == XMLOXIDE_NODE_ELEMENT) {
        char *name = xmlNodeGetName(cur);
        char *content = xmlNodeGetContent(cur);
        printf(&quot;  %s: %s\n&quot;, name, content);
        xmlFree(name);
        xmlFree(content);
    }
    xmlNodePtr next = xmlNodeGetNext(cur);
    xmlFreeNode(cur);
    cur = next;
}
xmlFreeNode(root);
xmlFreeDoc(doc);"><pre><span class="pl-k">#include</span> <span class="pl-s">"libxml2_compat.h"</span>

<span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmlReadMemory</span>(<span class="pl-s1">buf</span>, <span class="pl-s1">size</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">0</span>);
<span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">root</span> <span class="pl-c1">=</span> <span class="pl-en">xmlDocGetRootElement</span>(<span class="pl-s1">doc</span>);
<span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">root_name</span> <span class="pl-c1">=</span> <span class="pl-en">xmlNodeGetName</span>(<span class="pl-s1">root</span>);
<span class="pl-en">printf</span>(<span class="pl-s">"Root: %s\n"</span>, <span class="pl-s1">root_name</span>);
<span class="pl-en">xmlFree</span>(<span class="pl-s1">root_name</span>);

<span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">cur</span> <span class="pl-c1">=</span> <span class="pl-en">xmlNodeGetChildren</span>(<span class="pl-s1">root</span>);
<span class="pl-k">while</span> (<span class="pl-s1">cur</span>) {
    <span class="pl-k">if</span> (<span class="pl-en">xmlNodeGetType</span>(<span class="pl-s1">cur</span>) <span class="pl-c1">==</span> <span class="pl-c1">XMLOXIDE_NODE_ELEMENT</span>) {
        <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">name</span> <span class="pl-c1">=</span> <span class="pl-en">xmlNodeGetName</span>(<span class="pl-s1">cur</span>);
        <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">content</span> <span class="pl-c1">=</span> <span class="pl-en">xmlNodeGetContent</span>(<span class="pl-s1">cur</span>);
        <span class="pl-en">printf</span>(<span class="pl-s">"  %s: %s\n"</span>, <span class="pl-s1">name</span>, <span class="pl-s1">content</span>);
        <span class="pl-en">xmlFree</span>(<span class="pl-s1">name</span>);
        <span class="pl-en">xmlFree</span>(<span class="pl-s1">content</span>);
    }
    <span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">next</span> <span class="pl-c1">=</span> <span class="pl-en">xmlNodeGetNext</span>(<span class="pl-s1">cur</span>);
    <span class="pl-en">xmlFreeNode</span>(<span class="pl-s1">cur</span>);
    <span class="pl-s1">cur</span> <span class="pl-c1">=</span> <span class="pl-s1">next</span>;
}
<span class="pl-en">xmlFreeNode</span>(<span class="pl-s1">root</span>);
<span class="pl-en">xmlFreeDoc</span>(<span class="pl-s1">doc</span>);</pre></div>
<p dir="auto"><strong>Key changes:</strong></p>
<ul dir="auto">
<li>No <code>xmlInitParser()</code> / <code>xmlCleanupParser()</code></li>
<li><code>root-&gt;name</code> becomes <code>xmlNodeGetName(root)</code> (returns owned string)</li>
<li><code>root-&gt;children</code> becomes <code>xmlNodeGetChildren(root)</code> (returns handle)</li>
<li><code>cur-&gt;next</code> becomes <code>xmlNodeGetNext(cur)</code></li>
<li>Node handles must be freed with <code>xmlFreeNode()</code> when done</li>
<li>Strings from accessor functions are always owned and must be freed</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">XPath queries</h3><a id="user-content-xpath-queries" class="anchor" aria-label="Permalink: XPath queries" href="#xpath-queries"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>libxml2:</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="xmlXPathContextPtr ctx = xmlXPathNewContext(doc);
xmlXPathObjectPtr result = xmlXPathEvalExpression(&quot;//book/title&quot;, ctx);
if (result &amp;&amp; result-&gt;nodesetval) {
    for (int i = 0; i &lt; result-&gt;nodesetval-&gt;nodeNr; i++) {
        xmlNodePtr node = result-&gt;nodesetval-&gt;nodeTab[i];
        char *text = (char *)xmlNodeGetContent(node);
        printf(&quot;%s\n&quot;, text);
        xmlFree(text);
    }
}
xmlXPathFreeObject(result);
xmlXPathFreeContext(ctx);"><pre><span class="pl-smi">xmlXPathContextPtr</span> <span class="pl-s1">ctx</span> <span class="pl-c1">=</span> <span class="pl-en">xmlXPathNewContext</span>(<span class="pl-s1">doc</span>);
<span class="pl-smi">xmlXPathObjectPtr</span> <span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-en">xmlXPathEvalExpression</span>(<span class="pl-s">"//book/title"</span>, <span class="pl-s1">ctx</span>);
<span class="pl-k">if</span> (<span class="pl-s1">result</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">result</span><span class="pl-c1">-&gt;</span><span class="pl-c1">nodesetval</span>) {
    <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">result</span><span class="pl-c1">-&gt;</span><span class="pl-c1">nodesetval</span><span class="pl-c1">-&gt;</span><span class="pl-c1">nodeNr</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {
        <span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">node</span> <span class="pl-c1">=</span> <span class="pl-s1">result</span><span class="pl-c1">-&gt;</span><span class="pl-c1">nodesetval</span><span class="pl-c1">-&gt;</span><span class="pl-c1">nodeTab</span>[<span class="pl-s1">i</span>];
        <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">text</span> <span class="pl-c1">=</span> (<span class="pl-smi">char</span> <span class="pl-c1">*</span>)<span class="pl-en">xmlNodeGetContent</span>(<span class="pl-s1">node</span>);
        <span class="pl-en">printf</span>(<span class="pl-s">"%s\n"</span>, <span class="pl-s1">text</span>);
        <span class="pl-en">xmlFree</span>(<span class="pl-s1">text</span>);
    }
}
<span class="pl-en">xmlXPathFreeObject</span>(<span class="pl-s1">result</span>);
<span class="pl-en">xmlXPathFreeContext</span>(<span class="pl-s1">ctx</span>);</pre></div>
<p dir="auto"><strong>xmloxide (with compat header):</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="xmlNodePtr root = xmlDocGetRootElement(doc);
xmlXPathObjectPtr result = xmlXPathEval(&quot;//book/title&quot;, root);
if (result) {
    int count = xmlXPathNodeSetGetLength(result);
    for (int i = 0; i &lt; count; i++) {
        xmlNodePtr node = xmlXPathNodeSetItem(result, i, doc);
        char *text = xmlNodeGetContent(node);
        printf(&quot;%s\n&quot;, text);
        xmlFree(text);
        xmlFreeNode(node);
    }
}
xmlXPathFreeObject(result);
xmlFreeNode(root);"><pre><span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">root</span> <span class="pl-c1">=</span> <span class="pl-en">xmlDocGetRootElement</span>(<span class="pl-s1">doc</span>);
<span class="pl-smi">xmlXPathObjectPtr</span> <span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-en">xmlXPathEval</span>(<span class="pl-s">"//book/title"</span>, <span class="pl-s1">root</span>);
<span class="pl-k">if</span> (<span class="pl-s1">result</span>) {
    <span class="pl-smi">int</span> <span class="pl-s1">count</span> <span class="pl-c1">=</span> <span class="pl-en">xmlXPathNodeSetGetLength</span>(<span class="pl-s1">result</span>);
    <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">count</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {
        <span class="pl-smi">xmlNodePtr</span> <span class="pl-s1">node</span> <span class="pl-c1">=</span> <span class="pl-en">xmlXPathNodeSetItem</span>(<span class="pl-s1">result</span>, <span class="pl-s1">i</span>, <span class="pl-s1">doc</span>);
        <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">text</span> <span class="pl-c1">=</span> <span class="pl-en">xmlNodeGetContent</span>(<span class="pl-s1">node</span>);
        <span class="pl-en">printf</span>(<span class="pl-s">"%s\n"</span>, <span class="pl-s1">text</span>);
        <span class="pl-en">xmlFree</span>(<span class="pl-s1">text</span>);
        <span class="pl-en">xmlFreeNode</span>(<span class="pl-s1">node</span>);
    }
}
<span class="pl-en">xmlXPathFreeObject</span>(<span class="pl-s1">result</span>);
<span class="pl-en">xmlFreeNode</span>(<span class="pl-s1">root</span>);</pre></div>
<p dir="auto"><strong>Key changes:</strong></p>
<ul dir="auto">
<li>No <code>xmlXPathContext</code> needed — pass the context node directly</li>
<li><code>xmlXPathNodeSetItem()</code> takes the document pointer as an extra argument</li>
<li>Node handles from XPath results must be freed</li>
<li>Attribute-axis results are attribute nodes: <code>xmloxide_xpath_nodeset_item()</code>
returns the owner element's id for them, and
<code>xmloxide_xpath_nodeset_item_is_attribute()</code> /
<code>xmloxide_xpath_nodeset_item_attr_name()</code> /
<code>xmloxide_xpath_nodeset_item_attr_value()</code> expose the attribute itself
(libxml2 instead returns an <code>XML_ATTRIBUTE_NODE</code> from
<code>xmlXPathNodeSetItem</code>)</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Error handling</h3><a id="user-content-error-handling" class="anchor" aria-label="Permalink: Error handling" href="#error-handling"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>libxml2:</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="xmlSetGenericErrorFunc(NULL, my_error_handler);
xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);
if (!doc) {
    xmlErrorPtr err = xmlGetLastError();
    fprintf(stderr, &quot;Error at %d:%d: %s\n&quot;, err-&gt;line, err-&gt;int2, err-&gt;message);
}"><pre><span class="pl-en">xmlSetGenericErrorFunc</span>(<span class="pl-c1">NULL</span>, <span class="pl-s1">my_error_handler</span>);
<span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmlReadMemory</span>(<span class="pl-s1">buf</span>, <span class="pl-s1">size</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">0</span>);
<span class="pl-k">if</span> (!<span class="pl-s1">doc</span>) {
    <span class="pl-smi">xmlErrorPtr</span> <span class="pl-s1">err</span> <span class="pl-c1">=</span> <span class="pl-en">xmlGetLastError</span>();
    <span class="pl-en">fprintf</span>(<span class="pl-s1">stderr</span>, <span class="pl-s">"Error at %d:%d: %s\n"</span>, <span class="pl-s1">err</span><span class="pl-c1">-&gt;</span><span class="pl-c1">line</span>, <span class="pl-s1">err</span><span class="pl-c1">-&gt;</span><span class="pl-c1">int2</span>, <span class="pl-s1">err</span><span class="pl-c1">-&gt;</span><span class="pl-c1">message</span>);
}</pre></div>
<p dir="auto"><strong>xmloxide:</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="xmlDocPtr doc = xmlReadMemory(buf, size, NULL, NULL, 0);
if (!doc) {
    fprintf(stderr, &quot;Error at %u:%u: %s\n&quot;,
            xmloxide_last_error_line(),
            xmloxide_last_error_column(),
            xmloxide_last_error());
}"><pre><span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmlReadMemory</span>(<span class="pl-s1">buf</span>, <span class="pl-s1">size</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">NULL</span>, <span class="pl-c1">0</span>);
<span class="pl-k">if</span> (!<span class="pl-s1">doc</span>) {
    <span class="pl-en">fprintf</span>(<span class="pl-s1">stderr</span>, <span class="pl-s">"Error at %u:%u: %s\n"</span>,
            <span class="pl-en">xmloxide_last_error_line</span>(),
            <span class="pl-en">xmloxide_last_error_column</span>(),
            <span class="pl-en">xmloxide_last_error</span>());
}</pre></div>
<p dir="auto"><strong>Key changes:</strong></p>
<ul dir="auto">
<li>No error handler registration (use <code>xmloxide_last_error*()</code> functions)</li>
<li>Structured error info via <code>xmloxide_last_error_line()</code> / <code>_column()</code> / <code>_severity()</code></li>
<li>For document diagnostics (recovered errors), use <code>xmloxide_doc_diagnostic_*()</code> functions</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">HTML5 parsing (new in xmloxide)</h3><a id="user-content-html5-parsing-new-in-xmloxide" class="anchor" aria-label="Permalink: HTML5 parsing (new in xmloxide)" href="#html5-parsing-new-in-xmloxide"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">libxml2 ships an HTML 4.01 parser but has no WHATWG HTML5 parser. xmloxide
implements the full WHATWG HTML Living Standard tokenizer (section 13.2.5) and tree
builder (section 13.2.6), giving you spec-compliant HTML5 parsing out of the box.</p>
<p dir="auto"><strong>Rust:</strong></p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use xmloxide::html5::{parse_html5, parse_html5_with_options, Html5ParseOptions};
use xmloxide::html5::parse_html5_full;

// Full document parsing
let doc = parse_html5(&quot;&lt;p&gt;Hello &lt;b&gt;world&lt;/b&gt;&quot;).unwrap();

// Fragment parsing (the innerHTML algorithm)
let opts = Html5ParseOptions {
    scripting: false,
    fragment_context: Some(&quot;body&quot;.to_string()),
};
let doc = parse_html5_with_options(&quot;&lt;li&gt;Item 1&lt;li&gt;Item 2&quot;, &amp;opts).unwrap();

// Parse and collect all errors (always succeeds — no Result)
let result = parse_html5_full(&quot;&lt;p&gt;Hello&lt;/p&gt;&quot;);
println!(&quot;{} parse errors&quot;, result.errors.len());
let doc = result.document;"><pre><span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span>html5<span class="pl-kos">::</span><span class="pl-kos">{</span>parse_html5<span class="pl-kos">,</span> parse_html5_with_options<span class="pl-kos">,</span> <span class="pl-v">Html5ParseOptions</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span>html5<span class="pl-kos">::</span>parse_html5_full<span class="pl-kos">;</span>

<span class="pl-c">// Full document parsing</span>
<span class="pl-k">let</span> doc = <span class="pl-en">parse_html5</span><span class="pl-kos">(</span><span class="pl-s">"&lt;p&gt;Hello &lt;b&gt;world&lt;/b&gt;"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Fragment parsing (the innerHTML algorithm)</span>
<span class="pl-k">let</span> opts = <span class="pl-smi">Html5ParseOptions</span> <span class="pl-kos">{</span>
    <span class="pl-c1">scripting</span><span class="pl-kos">:</span> <span class="pl-c1">false</span><span class="pl-kos">,</span>
    <span class="pl-c1">fragment_context</span><span class="pl-kos">:</span> <span class="pl-en">Some</span><span class="pl-kos">(</span><span class="pl-s">"body"</span><span class="pl-kos">.</span><span class="pl-en">to_string</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> doc = <span class="pl-en">parse_html5_with_options</span><span class="pl-kos">(</span><span class="pl-s">"&lt;li&gt;Item 1&lt;li&gt;Item 2"</span><span class="pl-kos">,</span> <span class="pl-c1">&amp;</span>opts<span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Parse and collect all errors (always succeeds — no Result)</span>
<span class="pl-k">let</span> result = <span class="pl-en">parse_html5_full</span><span class="pl-kos">(</span><span class="pl-s">"&lt;p&gt;Hello&lt;/p&gt;"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">println</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-s">"{} parse errors"</span><span class="pl-kos">,</span> result<span class="pl-kos">.</span>errors<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">let</span> doc = result<span class="pl-kos">.</span><span class="pl-c1">document</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>C FFI:</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &quot;xmloxide.h&quot;

/* Full document parsing */
xmloxide_document *doc = xmloxide_parse_html5(&quot;&lt;p&gt;Hello &lt;b&gt;world&lt;/b&gt;&quot;);

/* Fragment parsing (innerHTML algorithm) */
xmloxide_document *frag = xmloxide_parse_html5_fragment(&quot;&lt;li&gt;A&lt;li&gt;B&quot;, &quot;ul&quot;);

/* HTML5 serialization */
char *html = xmloxide_serialize_html5(doc);
printf(&quot;%s\n&quot;, html);
xmloxide_free_string(html);

xmloxide_free_doc(frag);
xmloxide_free_doc(doc);"><pre><span class="pl-k">#include</span> <span class="pl-s">"xmloxide.h"</span>

<span class="pl-c">/* Full document parsing */</span>
<span class="pl-smi">xmloxide_document</span> <span class="pl-c1">*</span><span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_parse_html5</span>(<span class="pl-s">"&lt;p&gt;Hello &lt;b&gt;world&lt;/b&gt;"</span>);

<span class="pl-c">/* Fragment parsing (innerHTML algorithm) */</span>
<span class="pl-smi">xmloxide_document</span> <span class="pl-c1">*</span><span class="pl-s1">frag</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_parse_html5_fragment</span>(<span class="pl-s">"&lt;li&gt;A&lt;li&gt;B"</span>, <span class="pl-s">"ul"</span>);

<span class="pl-c">/* HTML5 serialization */</span>
<span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">html</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_serialize_html5</span>(<span class="pl-s1">doc</span>);
<span class="pl-en">printf</span>(<span class="pl-s">"%s\n"</span>, <span class="pl-s1">html</span>);
<span class="pl-en">xmloxide_free_string</span>(<span class="pl-s1">html</span>);

<span class="pl-en">xmloxide_free_doc</span>(<span class="pl-s1">frag</span>);
<span class="pl-en">xmloxide_free_doc</span>(<span class="pl-s1">doc</span>);</pre></div>
<p dir="auto"><strong>C FFI (with compat header):</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &quot;libxml2_compat.h&quot;

xmlDocPtr doc = xmloxide_parse_html5(&quot;&lt;p&gt;Hello &lt;b&gt;world&lt;/b&gt;&quot;);
xmlDocPtr frag = xmloxide_parse_html5_fragment(&quot;&lt;li&gt;A&lt;li&gt;B&quot;, &quot;ul&quot;);

char *html = xmloxide_serialize_html5(doc);
printf(&quot;%s\n&quot;, html);
xmloxide_free_string(html);

xmlFreeDoc(frag);
xmlFreeDoc(doc);"><pre><span class="pl-k">#include</span> <span class="pl-s">"libxml2_compat.h"</span>

<span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_parse_html5</span>(<span class="pl-s">"&lt;p&gt;Hello &lt;b&gt;world&lt;/b&gt;"</span>);
<span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">frag</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_parse_html5_fragment</span>(<span class="pl-s">"&lt;li&gt;A&lt;li&gt;B"</span>, <span class="pl-s">"ul"</span>);

<span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">html</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_serialize_html5</span>(<span class="pl-s1">doc</span>);
<span class="pl-en">printf</span>(<span class="pl-s">"%s\n"</span>, <span class="pl-s1">html</span>);
<span class="pl-en">xmloxide_free_string</span>(<span class="pl-s1">html</span>);

<span class="pl-en">xmlFreeDoc</span>(<span class="pl-s1">frag</span>);
<span class="pl-en">xmlFreeDoc</span>(<span class="pl-s1">doc</span>);</pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">HTML5 streaming (SAX-like, Rust only)</h3><a id="user-content-html5-streaming-sax-like-rust-only" class="anchor" aria-label="Permalink: HTML5 streaming (SAX-like, Rust only)" href="#html5-streaming-sax-like-rust-only"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">xmloxide provides a streaming SAX-like API for HTML5 that fires callbacks for
each token without building a DOM tree. This is useful for large documents
where you only need to extract specific data.</p>
<p dir="auto"><strong>Note:</strong> The C FFI SAX interface is XML-only. HTML5 streaming is available
only from Rust.</p>
<p dir="auto"><strong>Rust:</strong></p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use xmloxide::html5::sax::{Html5SaxHandler, parse_html5_sax};

struct LinkExtractor {
    hrefs: Vec&lt;String&gt;,
}

impl Html5SaxHandler for LinkExtractor {
    fn start_element(
        &amp;mut self,
        name: &amp;str,
        attributes: &amp;[(String, String)],
        _self_closing: bool,
    ) {
        if name == &quot;a&quot; {
            if let Some((_, href)) = attributes.iter().find(|(n, _)| n == &quot;href&quot;) {
                self.hrefs.push(href.clone());
            }
        }
    }
}

let mut handler = LinkExtractor { hrefs: Vec::new() };
parse_html5_sax(
    r#&quot;&lt;a href=&quot;https://example.com&quot;&gt;Link&lt;/a&gt;&lt;a href=&quot;/about&quot;&gt;About&lt;/a&gt;&quot;#,
    &amp;mut handler,
);
assert_eq!(handler.hrefs.len(), 2);"><pre><span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span>html5<span class="pl-kos">::</span>sax<span class="pl-kos">::</span><span class="pl-kos">{</span><span class="pl-v">Html5SaxHandler</span><span class="pl-kos">,</span> parse_html5_sax<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">struct</span> <span class="pl-smi">LinkExtractor</span> <span class="pl-kos">{</span>
    <span class="pl-c1">hrefs</span><span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">&lt;</span><span class="pl-smi">String</span><span class="pl-kos">&gt;</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span>

<span class="pl-k">impl</span> <span class="pl-smi">Html5SaxHandler</span> <span class="pl-k">for</span> <span class="pl-smi">LinkExtractor</span> <span class="pl-kos">{</span>
    <span class="pl-k">fn</span> <span class="pl-en">start_element</span><span class="pl-kos">(</span>
        <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> <span class="pl-smi">self</span><span class="pl-kos">,</span>
        <span class="pl-s1">name</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-smi">str</span><span class="pl-kos">,</span>
        <span class="pl-s1">attributes</span><span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-kos">[</span><span class="pl-kos">(</span><span class="pl-smi">String</span><span class="pl-kos">,</span> <span class="pl-smi">String</span><span class="pl-kos">)</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
        <span class="pl-s1">_self_closing</span><span class="pl-kos">:</span> <span class="pl-smi">bool</span><span class="pl-kos">,</span>
    <span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">if</span> name == <span class="pl-s">"a"</span> <span class="pl-kos">{</span>
            <span class="pl-k">if</span> <span class="pl-k">let</span> <span class="pl-v">Some</span><span class="pl-kos">(</span><span class="pl-kos">(</span>_<span class="pl-kos">,</span> href<span class="pl-kos">)</span><span class="pl-kos">)</span> = attributes<span class="pl-kos">.</span><span class="pl-en">iter</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">find</span><span class="pl-kos">(</span>|<span class="pl-kos">(</span>n<span class="pl-kos">,</span> _<span class="pl-kos">)</span>| n == <span class="pl-s">"href"</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
                <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-c1">hrefs</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span>href<span class="pl-kos">.</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
            <span class="pl-kos">}</span>
        <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">let</span> <span class="pl-k">mut</span> handler = <span class="pl-smi">LinkExtractor</span> <span class="pl-kos">{</span> <span class="pl-c1">hrefs</span><span class="pl-kos">:</span> <span class="pl-smi">Vec</span><span class="pl-kos">::</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-en">parse_html5_sax</span><span class="pl-kos">(</span>
    <span class="pl-s">r#"&lt;a href="https://example.com"&gt;Link&lt;/a&gt;&lt;a href="/about"&gt;About&lt;/a&gt;"#</span><span class="pl-kos">,</span>
    <span class="pl-c1">&amp;</span><span class="pl-k">mut</span> handler<span class="pl-kos">,</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>handler<span class="pl-kos">.</span>hrefs<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Available callbacks on <code>Html5SaxHandler</code> (all have default no-op implementations):</p>
<ul dir="auto">
<li><code>start_element(name, attributes, self_closing)</code> — start tags</li>
<li><code>end_element(name)</code> — end tags</li>
<li><code>characters(content)</code> — text content (coalesced)</li>
<li><code>comment(content)</code> — HTML comments</li>
<li><code>doctype(name, public_id, system_id)</code> — DOCTYPE declarations</li>
<li><code>error(error)</code> — tokenizer errors</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Schematron validation (new in xmloxide)</h3><a id="user-content-schematron-validation-new-in-xmloxide" class="anchor" aria-label="Permalink: Schematron validation (new in xmloxide)" href="#schematron-validation-new-in-xmloxide"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">libxml2 has limited Schematron support (only basic assert/report). xmloxide
implements ISO Schematron (ISO/IEC 19757-3) with phases, abstract patterns,
and <code>is-a</code> instantiation.</p>
<p dir="auto"><strong>Rust:</strong></p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use xmloxide::Document;
use xmloxide::validation::schematron::{
    parse_schematron, validate_schematron, validate_schematron_with_phase,
};

// Parse the Schematron schema
let schema = parse_schematron(r#&quot;
  &lt;schema xmlns=&quot;http://purl.oclc.org/dml/schematron&quot;&gt;
    &lt;phase id=&quot;quick&quot;&gt;
      &lt;active pattern=&quot;structure&quot;/&gt;
    &lt;/phase&gt;
    &lt;pattern id=&quot;structure&quot;&gt;
      &lt;rule context=&quot;/order&quot;&gt;
        &lt;assert test=&quot;@id&quot;&gt;Order must have an id attribute&lt;/assert&gt;
        &lt;assert test=&quot;item&quot;&gt;Order must contain at least one item&lt;/assert&gt;
      &lt;/rule&gt;
    &lt;/pattern&gt;
    &lt;pattern id=&quot;business-rules&quot;&gt;
      &lt;rule context=&quot;/order/item&quot;&gt;
        &lt;assert test=&quot;@price &gt; 0&quot;&gt;Price must be positive&lt;/assert&gt;
      &lt;/rule&gt;
    &lt;/pattern&gt;
  &lt;/schema&gt;
&quot;#).unwrap();

let doc = Document::parse_str(r#&quot;&lt;order id=&quot;123&quot;&gt;&lt;item price=&quot;10&quot;/&gt;&lt;/order&gt;&quot;#).unwrap();

// Validate against all patterns
let result = validate_schematron(&amp;doc, &amp;schema);
assert!(result.is_valid);

// Validate against a specific phase (only &quot;structure&quot; patterns)
let result = validate_schematron_with_phase(&amp;doc, &amp;schema, &quot;quick&quot;);
assert!(result.is_valid);

// Inspect validation errors
if !result.is_valid {
    for error in &amp;result.errors {
        eprintln!(&quot;{}:{} {}&quot;, error.line.unwrap_or(0), error.column.unwrap_or(0), error.message);
    }
}"><pre><span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span><span class="pl-v">Document</span><span class="pl-kos">;</span>
<span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span>validation<span class="pl-kos">::</span>schematron<span class="pl-kos">::</span><span class="pl-kos">{</span>
    parse_schematron<span class="pl-kos">,</span> validate_schematron<span class="pl-kos">,</span> validate_schematron_with_phase<span class="pl-kos">,</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-c">// Parse the Schematron schema</span>
<span class="pl-k">let</span> schema = <span class="pl-en">parse_schematron</span><span class="pl-kos">(</span><span class="pl-s">r#"</span>
<span class="pl-s">  &lt;schema xmlns="http://purl.oclc.org/dml/schematron"&gt;</span>
<span class="pl-s">    &lt;phase id="quick"&gt;</span>
<span class="pl-s">      &lt;active pattern="structure"/&gt;</span>
<span class="pl-s">    &lt;/phase&gt;</span>
<span class="pl-s">    &lt;pattern id="structure"&gt;</span>
<span class="pl-s">      &lt;rule context="/order"&gt;</span>
<span class="pl-s">        &lt;assert test="@id"&gt;Order must have an id attribute&lt;/assert&gt;</span>
<span class="pl-s">        &lt;assert test="item"&gt;Order must contain at least one item&lt;/assert&gt;</span>
<span class="pl-s">      &lt;/rule&gt;</span>
<span class="pl-s">    &lt;/pattern&gt;</span>
<span class="pl-s">    &lt;pattern id="business-rules"&gt;</span>
<span class="pl-s">      &lt;rule context="/order/item"&gt;</span>
<span class="pl-s">        &lt;assert test="@price &gt; 0"&gt;Price must be positive&lt;/assert&gt;</span>
<span class="pl-s">      &lt;/rule&gt;</span>
<span class="pl-s">    &lt;/pattern&gt;</span>
<span class="pl-s">  &lt;/schema&gt;</span>
<span class="pl-s">"#</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> doc = <span class="pl-smi">Document</span><span class="pl-kos">::</span><span class="pl-en">parse_str</span><span class="pl-kos">(</span><span class="pl-s">r#"&lt;order id="123"&gt;&lt;item price="10"/&gt;&lt;/order&gt;"#</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Validate against all patterns</span>
<span class="pl-k">let</span> result = <span class="pl-en">validate_schematron</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> <span class="pl-c1">&amp;</span>schema<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert</span><span class="pl-en">!</span><span class="pl-kos">(</span>result<span class="pl-kos">.</span>is_valid<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Validate against a specific phase (only "structure" patterns)</span>
<span class="pl-k">let</span> result = <span class="pl-en">validate_schematron_with_phase</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> <span class="pl-c1">&amp;</span>schema<span class="pl-kos">,</span> <span class="pl-s">"quick"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert</span><span class="pl-en">!</span><span class="pl-kos">(</span>result<span class="pl-kos">.</span>is_valid<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Inspect validation errors</span>
<span class="pl-k">if</span> !result<span class="pl-kos">.</span><span class="pl-c1">is_valid</span> <span class="pl-kos">{</span>
    <span class="pl-k">for</span> error <span class="pl-k">in</span> <span class="pl-c1">&amp;</span>result<span class="pl-kos">.</span><span class="pl-c1">errors</span> <span class="pl-kos">{</span>
        <span class="pl-en">eprintln</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-s">"{}:{} {}"</span><span class="pl-kos">,</span> error<span class="pl-kos">.</span>line<span class="pl-kos">.</span>unwrap_or<span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">,</span> error<span class="pl-kos">.</span>column<span class="pl-kos">.</span>unwrap_or<span class="pl-kos">(</span><span class="pl-c1">0</span><span class="pl-kos">)</span><span class="pl-kos">,</span> error<span class="pl-kos">.</span>message<span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>C FFI:</strong></p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &quot;xmloxide.h&quot;

const char *schema_xml = &quot;&lt;schema xmlns='http://purl.oclc.org/dml/schematron'&gt;&quot;
    &quot;&lt;pattern id='p1'&gt;&quot;
    &quot;  &lt;rule context='/order'&gt;&quot;
    &quot;    &lt;assert test='@id'&gt;Order must have an id&lt;/assert&gt;&quot;
    &quot;  &lt;/rule&gt;&quot;
    &quot;&lt;/pattern&gt;&quot;
    &quot;&lt;/schema&gt;&quot;;

/* Parse schema */
xmloxide_schematron_schema *schema = xmloxide_parse_schematron(schema_xml);

/* Parse document */
xmloxide_document *doc = xmloxide_parse(&quot;&lt;order id='1'&gt;&lt;item/&gt;&lt;/order&gt;&quot;);

/* Validate (all patterns) */
xmloxide_validation_result *result = xmloxide_validate_schematron(doc, schema);
if (xmloxide_validation_is_valid(result)) {
    printf(&quot;Valid!\n&quot;);
} else {
    size_t n = xmloxide_validation_error_count(result);
    for (size_t i = 0; i &lt; n; i++) {
        char *msg = xmloxide_validation_error_message(result, i);
        printf(&quot;Error: %s\n&quot;, msg);
        xmloxide_free_string(msg);
    }
}
xmloxide_free_validation_result(result);

/* Validate with a specific phase */
result = xmloxide_validate_schematron_with_phase(doc, schema, &quot;quick&quot;);
xmloxide_free_validation_result(result);

xmloxide_free_schematron(schema);
xmloxide_free_doc(doc);"><pre><span class="pl-k">#include</span> <span class="pl-s">"xmloxide.h"</span>

<span class="pl-k">const</span> <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">schema_xml</span> <span class="pl-c1">=</span> <span class="pl-s">"&lt;schema xmlns='http://purl.oclc.org/dml/schematron'&gt;"</span>
    <span class="pl-s">"&lt;pattern id='p1'&gt;"</span>
    <span class="pl-s">"  &lt;rule context='/order'&gt;"</span>
    <span class="pl-s">"    &lt;assert test='@id'&gt;Order must have an id&lt;/assert&gt;"</span>
    <span class="pl-s">"  &lt;/rule&gt;"</span>
    <span class="pl-s">"&lt;/pattern&gt;"</span>
    <span class="pl-s">"&lt;/schema&gt;"</span>;

<span class="pl-c">/* Parse schema */</span>
<span class="pl-smi">xmloxide_schematron_schema</span> <span class="pl-c1">*</span><span class="pl-s1">schema</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_parse_schematron</span>(<span class="pl-s1">schema_xml</span>);

<span class="pl-c">/* Parse document */</span>
<span class="pl-smi">xmloxide_document</span> <span class="pl-c1">*</span><span class="pl-s1">doc</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_parse</span>(<span class="pl-s">"&lt;order id='1'&gt;&lt;item/&gt;&lt;/order&gt;"</span>);

<span class="pl-c">/* Validate (all patterns) */</span>
<span class="pl-smi">xmloxide_validation_result</span> <span class="pl-c1">*</span><span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_validate_schematron</span>(<span class="pl-s1">doc</span>, <span class="pl-s1">schema</span>);
<span class="pl-k">if</span> (<span class="pl-en">xmloxide_validation_is_valid</span>(<span class="pl-s1">result</span>)) {
    <span class="pl-en">printf</span>(<span class="pl-s">"Valid!\n"</span>);
} <span class="pl-k">else</span> {
    <span class="pl-smi">size_t</span> <span class="pl-s1">n</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_validation_error_count</span>(<span class="pl-s1">result</span>);
    <span class="pl-k">for</span> (<span class="pl-smi">size_t</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">n</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {
        <span class="pl-smi">char</span> <span class="pl-c1">*</span><span class="pl-s1">msg</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_validation_error_message</span>(<span class="pl-s1">result</span>, <span class="pl-s1">i</span>);
        <span class="pl-en">printf</span>(<span class="pl-s">"Error: %s\n"</span>, <span class="pl-s1">msg</span>);
        <span class="pl-en">xmloxide_free_string</span>(<span class="pl-s1">msg</span>);
    }
}
<span class="pl-en">xmloxide_free_validation_result</span>(<span class="pl-s1">result</span>);

<span class="pl-c">/* Validate with a specific phase */</span>
<span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-en">xmloxide_validate_schematron_with_phase</span>(<span class="pl-s1">doc</span>, <span class="pl-s1">schema</span>, <span class="pl-s">"quick"</span>);
<span class="pl-en">xmloxide_free_validation_result</span>(<span class="pl-s1">result</span>);

<span class="pl-en">xmloxide_free_schematron</span>(<span class="pl-s1">schema</span>);
<span class="pl-en">xmloxide_free_doc</span>(<span class="pl-s1">doc</span>);</pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">CSS selectors (new in xmloxide, Rust only)</h3><a id="user-content-css-selectors-new-in-xmloxide-rust-only" class="anchor" aria-label="Permalink: CSS selectors (new in xmloxide, Rust only)" href="#css-selectors-new-in-xmloxide-rust-only"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">libxml2 has no CSS selector API — it uses XPath exclusively. xmloxide provides
a <code>css::select</code> function that supports a broad set of CSS selectors as an
alternative to XPath for element queries.</p>
<p dir="auto"><strong>Rust:</strong></p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use xmloxide::css::select;
use xmloxide::Document;

let doc = Document::parse_str(r#&quot;
    &lt;html&gt;
      &lt;body&gt;
        &lt;div class=&quot;content&quot;&gt;
          &lt;p id=&quot;intro&quot;&gt;Hello&lt;/p&gt;
          &lt;p class=&quot;highlight&quot;&gt;World&lt;/p&gt;
          &lt;ul&gt;
            &lt;li class=&quot;active&quot;&gt;One&lt;/li&gt;
            &lt;li&gt;Two&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/body&gt;
    &lt;/html&gt;
&quot;#).unwrap();

let root = doc.root_element().unwrap();

// Tag selector
let paragraphs = select(&amp;doc, root, &quot;p&quot;).unwrap();
assert_eq!(paragraphs.len(), 2);

// Class selector
let highlighted = select(&amp;doc, root, &quot;.highlight&quot;).unwrap();
assert_eq!(highlighted.len(), 1);

// ID selector
let intro = select(&amp;doc, root, &quot;#intro&quot;).unwrap();
assert_eq!(intro.len(), 1);

// Combinators and pseudo-classes
let first_li = select(&amp;doc, root, &quot;ul &gt; li:first-child&quot;).unwrap();
assert_eq!(first_li.len(), 1);

// Attribute selectors
let active = select(&amp;doc, root, &quot;[class~='active']&quot;).unwrap();
assert_eq!(active.len(), 1);"><pre><span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span>css<span class="pl-kos">::</span>select<span class="pl-kos">;</span>
<span class="pl-k">use</span> xmloxide<span class="pl-kos">::</span><span class="pl-v">Document</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> doc = <span class="pl-smi">Document</span><span class="pl-kos">::</span><span class="pl-en">parse_str</span><span class="pl-kos">(</span><span class="pl-s">r#"</span>
<span class="pl-s">    &lt;html&gt;</span>
<span class="pl-s">      &lt;body&gt;</span>
<span class="pl-s">        &lt;div class="content"&gt;</span>
<span class="pl-s">          &lt;p id="intro"&gt;Hello&lt;/p&gt;</span>
<span class="pl-s">          &lt;p class="highlight"&gt;World&lt;/p&gt;</span>
<span class="pl-s">          &lt;ul&gt;</span>
<span class="pl-s">            &lt;li class="active"&gt;One&lt;/li&gt;</span>
<span class="pl-s">            &lt;li&gt;Two&lt;/li&gt;</span>
<span class="pl-s">          &lt;/ul&gt;</span>
<span class="pl-s">        &lt;/div&gt;</span>
<span class="pl-s">      &lt;/body&gt;</span>
<span class="pl-s">    &lt;/html&gt;</span>
<span class="pl-s">"#</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> root = doc<span class="pl-kos">.</span><span class="pl-en">root_element</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Tag selector</span>
<span class="pl-k">let</span> paragraphs = <span class="pl-en">select</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> root<span class="pl-kos">,</span> <span class="pl-s">"p"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>paragraphs<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Class selector</span>
<span class="pl-k">let</span> highlighted = <span class="pl-en">select</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> root<span class="pl-kos">,</span> <span class="pl-s">".highlight"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>highlighted<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// ID selector</span>
<span class="pl-k">let</span> intro = <span class="pl-en">select</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> root<span class="pl-kos">,</span> <span class="pl-s">"#intro"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>intro<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Combinators and pseudo-classes</span>
<span class="pl-k">let</span> first_li = <span class="pl-en">select</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> root<span class="pl-kos">,</span> <span class="pl-s">"ul &gt; li:first-child"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>first_li<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Attribute selectors</span>
<span class="pl-k">let</span> active = <span class="pl-en">select</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>doc<span class="pl-kos">,</span> root<span class="pl-kos">,</span> <span class="pl-s">"[class~='active']"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">unwrap</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-en">assert_eq</span><span class="pl-en">!</span><span class="pl-kos">(</span>active<span class="pl-kos">.</span>len<span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Supported selectors include: tag, <code>.class</code>, <code>#id</code>, <code>*</code>, <code>[attr]</code>,
<code>[attr="value"]</code>, <code>[attr^=]</code>, <code>[attr$=]</code>, <code>[attr*=]</code>, <code>[attr~=]</code>,
<code>[attr|=]</code>, descendant (space), child (<code>&gt;</code>), adjacent (<code>+</code>), general
sibling (<code>~</code>), grouping (<code>,</code>), <code>:first-child</code>, <code>:last-child</code>, <code>:only-child</code>,
<code>:empty</code>, <code>:not()</code>, and <code>:nth-child()</code>.</p>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">What's NOT compatible</h2><a id="user-content-whats-not-compatible" class="anchor" aria-label="Permalink: What's NOT compatible" href="#whats-not-compatible"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">These libxml2 patterns require code changes and cannot be papered over:</p>
<ol dir="auto">
<li><strong>Direct struct member access</strong> — <code>node-&gt;name</code>, <code>node-&gt;type</code>, <code>node-&gt;children</code>, <code>node-&gt;ns</code>. Use accessor functions instead.</li>
<li><strong>Pointer-based iteration</strong> — <code>for (cur = node-&gt;children; cur; cur = cur-&gt;next)</code>. Use <code>xmlNodeGetChildren()</code> + <code>xmlNodeGetNext()</code>.</li>
<li><strong>Custom error handlers</strong> — <code>xmlSetGenericErrorFunc()</code>. Use <code>xmloxide_last_error*()</code>.</li>
<li><strong>Parser context manipulation</strong> — <code>xmlNewParserCtxt()</code>, <code>xmlCtxtReadMemory()</code>. Use the simpler parse functions directly.</li>
<li><strong>Custom entity loaders</strong> — <code>xmlSetExternalEntityLoader()</code>. Not exposed.</li>
<li><strong>XSLT</strong> — Out of scope (separate library in both libxml2 and xmloxide).</li>
</ol>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Thread safety</h2><a id="user-content-thread-safety" class="anchor" aria-label="Permalink: Thread safety" href="#thread-safety"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Unlike libxml2, xmloxide requires <strong>no synchronization</strong> for independent documents. Each <code>xmlDocPtr</code> is fully self-contained. The only shared state is the per-thread error message (<code>xmloxide_last_error()</code>), which uses thread-local storage.</p>
<div class="highlight highlight-source-c notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/* Safe: different threads, different documents */
/* Thread 1 */ xmlDocPtr doc1 = xmlParseDoc(xml1);
/* Thread 2 */ xmlDocPtr doc2 = xmlParseDoc(xml2);

/* NOT safe: same document from multiple threads without synchronization */
/* Use a mutex if you need to share a document across threads */"><pre><span class="pl-c">/* Safe: different threads, different documents */</span>
<span class="pl-c">/* Thread 1 */</span> <span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc1</span> <span class="pl-c1">=</span> <span class="pl-en">xmlParseDoc</span>(<span class="pl-s1">xml1</span>);
<span class="pl-c">/* Thread 2 */</span> <span class="pl-smi">xmlDocPtr</span> <span class="pl-s1">doc2</span> <span class="pl-c1">=</span> <span class="pl-en">xmlParseDoc</span>(<span class="pl-s1">xml2</span>);

<span class="pl-c">/* NOT safe: same document from multiple threads without synchronization */</span>
<span class="pl-c">/* Use a mutex if you need to share a document across threads */</span></pre></div>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 p-responsive" role="contentinfo"  >
  <h2 class='sr-only'>Footer</h2>

  


  <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
    <div class="d-flex flex-items-center flex-shrink-0 mx-2">
      <a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
        <svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
    <path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
      <span>
        &copy; 2026 GitHub,&nbsp;Inc.
      </span>
    </div>

    <nav aria-label="Footer">
      <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>

      <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">


          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
          </li>


            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
            </li>

            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
            </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://github.community/" data-view-component="true" class="Link--secondary Link">Community</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
          </li>

          
<li class="mx-2" >
  <cookie-consent-link>
    <button
      type="button"
      class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
      data-action="click:cookie-consent-link#showConsentManagement"
      data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
    >
      Manage cookies
    </button>
  </cookie-consent-link>
</li>

  <li class="mx-2">
    <cookie-consent-link>
      <button
        type="button"
        class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
        data-action="click:cookie-consent-link#showConsentManagement"
        data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
      >
        Do not share my personal information
      </button>
    </cookie-consent-link>
  </li>

      </ul>
    </nav>
  </div>
</footer>



    <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
      data-locale="en"
      data-initial-cookie-consent-allowed=""
      data-cookie-consent-required="true"
    ></ghcc-consent>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    You can’t perform that action at this time.
  </div>

    <template id="site-details-dialog">
  <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
    <summary role="button" aria-label="Close dialog"></summary>
    <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
      <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
      </button>
      <div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
    </details-dialog>
  </details>
</template>

    <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
  <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
  </div>
</div>

    <template id="snippet-clipboard-copy-button">
  <div class="zeroclipboard-container position-absolute right-0 top-0">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
  <div class="zeroclipboard-container">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>




    </div>
    <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
    <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
  </body>
</html>

