Simplify creating Decoders for XML input.
Most code will only need the two types, the decodeXml function, and the optionalTag & multipleTag decoders.
Example:
import XML.Extra exposing ( TagSpec, Required(..)
, decodeXml, optionalTag
)
import Json.Decode as JD exposing ( Decoder )
type alias PersonRecord =
{ name : String
, age : Int
, spouse : Maybe Person
, children : List Person
}
type Person =
Person PersonRecord
personDecoder : Decoder Person
personDecoder =
JD.map4 (\name age spouse children ->
Person <| PersonRecord name age spouse children
(JD.field "name" JD.string)
(JD.field "age" JD.int)
(optionalTag "spouse"
(JD.lazy (\_ -> personDecoder))
personTagSpecs
)
(multipleTag "child"
(JD.lazy (\_ -> personDecoder))
personTagSpecs)
personTagSpecs : List TagSpec
personTagSpecs =
[ ("name", Required)
, ("age", Required)
, ("spouse", Optional)
, ("child", Multiple)
]
decodePersonXml : String -> Result String Person
decodePersonXml xml =
decodeXml xml "person" personDecoder personTagSpecs
Xml =
"""
<person>
<name>Irving</name>
<age max="100">30</age>
<sex>yes</sex>
<favoriteColor>blue</favoriteColor>
<spouse>
<name>Joan</name>
<age>28</age>
</spouse>
<child>
<name>Bob</name>
<age>1</age>
</child>
<child>
<name>Sally</name>
<age>3</age>
</child>
</person>
"""How to handle a tag in a TagSpec.
Required tags error if not there.
RequiredIgnore tags must be in the XML, but are not returned.
Optional tags will become null if not in the XML.
Multiple tags become a list.
A decoder for Optional XML tags
A decoder for Multiple XML tags
Decode an XML string containing a single tag into an Elm value.
Decode the contents of an XML tag with subtags.
Each TagSpec pulls one or more matching tags from the list.
Unspecified tags in the parsed Value are skipped.
You end up with a single JSON object, with the tags as keys, to which you can apply a standard JSON decoder.
Decode an XML string into a simplified Json.Encode.Value.
Convert the Xml.Value returned by Xml.Decode.decode to a Json.Encode.Value,
removing all the attributes.
A description of one tag to decode: (<tag name>, Required, <tag decoder>)