{"id":13509759,"url":"https://github.com/processone/fast_xml","last_synced_at":"2025-05-15T10:01:31.825Z","repository":{"id":43189031,"uuid":"46738594","full_name":"processone/fast_xml","owner":"processone","description":"Fast Expat based Erlang XML parsing library","archived":false,"fork":false,"pushed_at":"2024-12-18T16:09:00.000Z","size":621,"stargazers_count":135,"open_issues_count":5,"forks_count":45,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-14T16:53:42.000Z","etag":null,"topics":["elixir","erlang","erlang-xml-parser","xml","xml-stream-parsing","xmpp"],"latest_commit_sha":null,"homepage":null,"language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/processone.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-23T18:04:45.000Z","updated_at":"2025-02-24T11:00:10.000Z","dependencies_parsed_at":"2023-12-27T00:22:40.988Z","dependency_job_id":"74336ac8-72c7-4fe4-9329-3d3d98335790","html_url":"https://github.com/processone/fast_xml","commit_stats":{"total_commits":409,"total_committers":17,"mean_commits":"24.058823529411764","dds":0.7310513447432763,"last_synced_commit":"e7dc91310046831f436a03abf029587f0c2764f4"},"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/processone%2Ffast_xml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/processone%2Ffast_xml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/processone%2Ffast_xml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/processone%2Ffast_xml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/processone","download_url":"https://codeload.github.com/processone/fast_xml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319715,"owners_count":22051072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","erlang","erlang-xml-parser","xml","xml-stream-parsing","xmpp"],"created_at":"2024-08-01T02:01:12.583Z","updated_at":"2025-05-15T10:01:31.158Z","avatar_url":"https://github.com/processone.png","language":"Erlang","funding_links":[],"categories":["XML","Text and Numbers","Processing Libraries"],"sub_categories":["XML","Libraries"],"readme":"# Erlang and Elixir XML Parsing\n\n[![CI](https://github.com/processone/fast_xml/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/processone/fast_xml/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/processone/fast_xml/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/processone/fast_xml?branch=master)\n[![Hex version](https://img.shields.io/hexpm/v/fast_xml.svg \"Hex version\")](https://hex.pm/packages/fast_xml)\n\nFast Expat based Erlang XML parsing and manipulation library, with a\nstrong focus on XML stream parsing from network.\n\nIt supports:\n\n- Full XML structure parsing: Suitable for small but complete XML chunks.\n- XML stream parsing: Suitable for large XML document, or infinite\n  network XML stream like XMPP.\n\nThis module can parse files much faster than built-in module `xmerl`.\nDepending on file complexity and size `fxml_stream:parse_element/1` can\nbe 8-18 times faster than calling `xmerl_scan:string/2`.\n\nThis application was previously called\n[p1_xml](https://github.com/processone/xml) and was renamed after\nmajor optimisations to put emphasis on the fact it is damn fast.\n\n## Building\n\nErlang XML parser can be build as follow:\n\n    ./configure \u0026\u0026 make\n\nErlang XML parser is a rebar-compatible OTP\napplication. Alternatively, you can build it with rebar:\n\n    rebar compile\n\n## Dependencies\n\nErlang XML parser depends on Expat XML parser. You need development\nheaders for Expat library to build it.\n\nYou can use `configure` options to pass custom path to Expat libraries and headers:\n\n    --with-expat=[ARG]      use Expat XML Parser from given prefix (ARG=path);\n                            check standard prefixes (ARG=yes); disable (ARG=no)\n    --with-expat-inc=[DIR]  path to Expat XML Parser headers\n    --with-expat-lib=[ARG]  link options for Expat XML Parser libraries\n\n## xmlel record and types\n\nXML elements are provided as Erlang xmlel records.\n\nFormat of the record allows defining a simple tree-like\nstructure. xmlel record has the following fields:\n\n- name     :: binary()\n- attrs    :: [attr()]\n- children :: [xmlel() | cdata()]\n\ncdata type is a tuple of the form:\n\n    {xmlcdata, CData::binary()}\n\nattr type if a tuple of the form:\n\n    {Name::binary(), Value::binary()}\n\n## XML full structure parsing\n\nYou can definitely parse a complete XML structure with `fast_xml`:\n\n```shell\n$ erl -pa ebin\nErlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]\n\nEshell V6.3  (abort with ^G)\n1\u003e application:start(fast_xml).\nok\n2\u003e rr(fxml).\n[xmlel]\n3\u003e fxml_stream:parse_element(\u003c\u003c\"\u003ctest\u003econtent cdata\u003c/test\u003e\"\u003e\u003e).\n#xmlel{name = \u003c\u003c\"test\"\u003e\u003e,attrs = [],\n       children = [{xmlcdata,\u003c\u003c\"content cdata\"\u003e\u003e}]}\n```\n\n## XML Stream parsing example\n\nYou can also parse continuous stream. Our design allows decoupling\nvery easily the process receiving the raw XML to parse from the\nprocess receiving the parsed content.\n\nThe workflow is as follow:\n\n    state = new(CallbackPID); parse(state, data); parse(state, moredata); ...\n\nand the parsed XML fragments (stanzas) are send to CallbackPID.\n\nWith that approach you can be very flexible on how you architect your\nown application.\n\nHere is an example XML stream parsing:\n\n```shell\n$ erl -pa ebin\nErlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]\n\nEshell V6.3  (abort with ^G)\n\n% Start the application:\n1\u003e application:start(fast_xml).\nok\n\n% Create a new stream, using self PID to received XML parsing event:\n2\u003e S1 = fxml_stream:new(self()).\n\u003c\u003c\u003e\u003e\n\n% Start feeding content to the XML parser.\n3\u003e S2 = fxml_stream:parse(S1, \u003c\u003c\"\u003croot\u003e\"\u003e\u003e).\n\u003c\u003c\u003e\u003e\n\n% Receive Erlang message send to shell process:\n4\u003e flush().\nShell got {'$gen_event',{xmlstreamstart,\u003c\u003c\"root\"\u003e\u003e,[]}}\nok\n\n% Feed more content:\n5\u003e S3 = fxml_stream:parse(S2, \u003c\u003c\"\u003cxmlelement\u003econtent cdata\u003c/xmlelement\u003e\"\u003e\u003e).\n\u003c\u003c\u003e\u003e\n\n% Receive more messages:\n6\u003e flush().\nShell got {'$gen_event',\n              {xmlstreamelement,\n                  {xmlel,\u003c\u003c\"xmlelement\"\u003e\u003e,[],\n                      [{xmlcdata,\u003c\u003c\"content cdata\"\u003e\u003e}]}}}\nok\n\n% Feed more content:\n7\u003e S4 = fxml_stream:parse(S3, \u003c\u003c\"\u003c/root\u003e\"\u003e\u003e).      \n\u003c\u003c\u003e\u003e\n\n% Receive messages:\n8\u003e flush().\nShell got {'$gen_event',{xmlstreamend,\u003c\u003c\"root\"\u003e\u003e}}\nok\n\n9\u003e fxml_stream:close(S4).\ntrue\n```\n\nNote how the root element is important. We expect to have the root\nelement serve as boundary with stream start and stream end\nevent. Then, lower level tags are passed as sub stream elements.\n\n## How does this module relate to exmpp ?\n\nThis module is a low level fast XML parser. It is not an XMPP client\nlibrary like [exmpp](https://processone.github.io/exmpp/).\n\n## References\n\nThis module is use at large scale for parsing massive XML content in\n[ejabberd](https://www.ejabberd.im) XMPP server project. It is used in\nproduction in thousands of real life deployments.\n\n## Development\n\n### Test\n\n#### Unit test\n\nYou can run eunit test with the command:\n\n    $ rebar eunit\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprocessone%2Ffast_xml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprocessone%2Ffast_xml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprocessone%2Ffast_xml/lists"}