{"id":13509769,"url":"https://github.com/ewildgoose/elixir-xml_rpc","last_synced_at":"2025-04-04T08:04:43.449Z","repository":{"id":33512140,"uuid":"37158133","full_name":"ewildgoose/elixir-xml_rpc","owner":"ewildgoose","description":"Encode and decode elixir terms to XML-RPC parameters","archived":false,"fork":false,"pushed_at":"2024-12-09T11:19:46.000Z","size":83,"stargazers_count":40,"open_issues_count":2,"forks_count":17,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T07:03:17.086Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/ewildgoose.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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-06-09T21:00:07.000Z","updated_at":"2024-12-09T11:19:50.000Z","dependencies_parsed_at":"2024-06-19T09:54:53.173Z","dependency_job_id":"fad5b68d-1246-49ca-9a0e-f556d435f410","html_url":"https://github.com/ewildgoose/elixir-xml_rpc","commit_stats":{"total_commits":60,"total_committers":9,"mean_commits":6.666666666666667,"dds":0.2666666666666667,"last_synced_commit":"472389a490c20008df960f972d2cfa6f652a99a6"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewildgoose%2Felixir-xml_rpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewildgoose%2Felixir-xml_rpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewildgoose%2Felixir-xml_rpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ewildgoose%2Felixir-xml_rpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ewildgoose","download_url":"https://codeload.github.com/ewildgoose/elixir-xml_rpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247138187,"owners_count":20890007,"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":[],"created_at":"2024-08-01T02:01:12.746Z","updated_at":"2025-04-04T08:04:43.426Z","avatar_url":"https://github.com/ewildgoose.png","language":"Elixir","funding_links":[],"categories":["XML"],"sub_categories":[],"readme":"XmlRpc\n======\n\n[![Build Status](https://travis-ci.org/ewildgoose/elixir-xml_rpc.svg?branch=master)](https://travis-ci.org/ewildgoose/elixir-xml_rpc)\n[![Module Version](https://img.shields.io/hexpm/v/xmlrpc.svg)](https://hex.pm/packages/xmlrpc)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/xmlrpc/)\n[![Total Download](https://img.shields.io/hexpm/dt/xmlrpc.svg)](https://hex.pm/packages/xmlrpc)\n[![License](https://img.shields.io/hexpm/l/xmlrpc.svg)](https://github.com/ewildgoose/elixir-xml_rpc/blob/master/LICENSE)\n[![Last Updated](https://img.shields.io/github/last-commit/ewildgoose/elixir-xml_rpc.svg)](https://github.com/ewildgoose/elixir-xml_rpc/commits/master)\n\nEncode and decode elixir terms to [XML-RPC](http://wikipedia.org/wiki/XML-RPC) parameters.\nAll XML-RPC parameter types are supported, including arrays, structs and Nil (optional).\n\nThis module handles the parsing and encoding of the datatypes, but can be used\nin conjunction with HTTPoison, Phoenix, etc to create fully featured XML-RPC\nclients and servers.\n\nXML input (ie untrusted) is validated against an [XML Schema](http://en.wikipedia.org/wiki/XML_schema),\nwhich should help enforce correctness of input.  [erlsom](https://github.com/willemdj/erlsom)\nis used to decode the xml as xmerl creates atoms during decoding, which has\nthe risk that a malicious client can exhaust out atom space and crash the vm.\n\n\n## Installation\n\nAdd XML-RPC to your mix dependencies:\n\n```elixir\ndef deps do\n  [\n    {:xmlrpc, \"~\u003e 1.4\"}\n  ]\nend\n```\n\nThen run `mix deps.get` and `mix deps.compile`.\n\n\n## Datatypes\n\nXML-RPC only allows limited parameter types. We map these to Elixir as follows:\n\n| XMLRPC               | Elixir                    |\n| ---------------------|---------------------------|\n| `\u003cboolean\u003e`          | Boolean, eg true/false    |\n| `\u003cstring\u003e`           | Bitstring, eg \"string\"    |\n| `\u003cint\u003e` (`\u003ci4\u003e`)     | Integer, eg 17            |\n| `\u003cdouble\u003e`           | Float, eg -12.3           |\n| `\u003carray\u003e`            | List, eg [1, 2, 3]        |\n| `\u003cstruct\u003e`           | Map, eg %{key: \"value\"}   |\n| `\u003cdateTime.iso8601\u003e` | %XMLRPC.DateTime          |\n| `\u003cbase64\u003e`           | %XMLRPC.Base64            |\n| `\u003cnil/\u003e` (optional)  | nil                       |\n\n\nNote that array and struct parameters can be composed of the fundamental types,\nand you can nest to arbitrary depths. (int inside a struct, inside an array, inside a struct, etc).\nCommon practice seems to be to use a struct (or sometimes an array) as the top\nlevel to pass (named) each way.\n\nThe XML encoding is performed through a protocol and so abstract datatypes\ncan be encoded by implementing the `XMLRPC.ValueEncoder` protocol.\n\n### Nil\n\nNil is not defined in the core specification, but is commonly implemented as\nan option.  The use of nil is enabled by default for encoding and decoding.\nIf you want a \u003cnil/\u003e input to be treated as an error then pass\n[exclude_nil: true] in the `options` parameter\n\n## API\n\nThe XML-RPC api consists of a call to a remote url, passing a \"method_name\"\nand a number of parameters.\n\n    %XMLRPC.MethodCall{method_name: \"test.sumprod\", params: [2,3]}\n\nThe response is either \"failure\" and a `fault_code` and `fault_string`, or a\nresponse which consists of a single parameter (use a struct/array to pass back\nmultiple values)\n\n    %XMLRPC.Fault{fault_code: 4, fault_string: \"Too many parameters.\"}\n\n    %XMLRPC.MethodResponse{param: 30}\n\nTo encode/decode to xml use `XMLRPC.encode/2` or `XMLRPC.decode/2`\n\n## Examples\n\n### Client using HTTPoison\n\n[HTTPoison](https://github.com/edgurgel/httpoison) can be used to talk to the remote API.  To encode the body we can\nsimply call `XMLRPC.encode/2`, and then decode the response with `XMLRPC.decode/2`\n\n```elixir\nrequest_body = %XMLRPC.MethodCall{method_name: \"test.sumprod\", params: [2,3]}\n                |\u003e XMLRPC.encode!\n\"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?\u003e\u003cmethodCall\u003e\u003cmethodName\u003etest.sumprod\u003c/methodName\u003e\u003cparams\u003e\u003cparam\u003e\u003cvalue\u003e\u003cint\u003e2\u003c/int\u003e\u003c/value\u003e\u003c/param\u003e\u003cparam\u003e\u003cvalue\u003e\u003cint\u003e3\u003c/int\u003e\u003c/value\u003e\u003c/param\u003e\u003c/params\u003e\u003c/methodCall\u003e\"\n\n# Now use HTTPoison to call your RPC\nresponse = HTTPoison.post!(\"http://www.advogato.org/XMLRPC\", request_body).body\n\n# eg\nresponse = \"\u003c?xml version=\\\"1.0\\\"?\u003e\u003cmethodResponse\u003e\u003cparams\u003e\u003cparam\u003e\u003cvalue\u003e\u003carray\u003e\u003cdata\u003e\u003cvalue\u003e\u003cint\u003e5\u003c/int\u003e\u003c/value\u003e\u003cvalue\u003e\u003cint\u003e6\u003c/int\u003e\u003c/value\u003e\u003c/data\u003e\u003c/array\u003e\u003c/value\u003e\u003c/param\u003e\u003c/params\u003e\u003c/methodResponse\u003e\"\n            |\u003e XMLRPC.decode\n{:ok, %XMLRPC.MethodResponse{param: [5, 6]}}\n```\nSee the [HTTPoison docs](https://github.com/edgurgel/httpoison#wrapping-httpoisonbase)\nfor more details, but you can also wrap the base API and have HTTPoison\nautomatically do your encoding and decoding.  In this way its very simple to build\nhigher level APIs:\n\n```elixir\ndefmodule XMLRPC do\n  use HTTPoison.Base\n\n  def process_request_body(body), do: XMLRPC.encode(body)\n  def process_response_body(body), do: XMLRPC.decode(body)\nend\n\niex\u003e request = %XMLRPC.MethodCall{method_name: \"test.sumprod\", params: [2,3]}\niex\u003e response = HTTPoison.post!(\"http://www.advogato.org/XMLRPC\", request).body\n{:ok, %XMLRPC.MethodResponse{param: [5, 6]}}\n```\n\nHTTPoison allows you to hook into other parts of the request process and handle\nauthentication, URL schemes and easily build out a complete API module.\n\n### Server\n\nUsing say Phoenix, you can handle an incoming request and decode as above.\nXMLRPC implements the `encode_to_iodata!` call, which allows pluggable response\nhandlers to automatically encode your response\n\n## Copyright and License\n\nCopyright (c) 2015 Ed Wildgoose\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fewildgoose%2Felixir-xml_rpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fewildgoose%2Felixir-xml_rpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fewildgoose%2Felixir-xml_rpc/lists"}