# Error converting XML to JSON and extracting values

**URL:** https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297
**Category:** Learn
**Created:** [April 26, 2021, 3:47pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297 "2021-04-26T15:47:06Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)
#### Post date: [April 26, 2021, 3:47pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297/1 "2021-04-26T15:47:06Z")

</div>

I’m using @billstclair’s XML parser package [elm-xml-eeue56 2.0.0](https://package.elm-lang.org/packages/billstclair/elm-xml-eeue56/2.0.0/)

But `elm/json` doesn’t seem to like it’s output.

* * *

I have a simple input:  
`<summary>\"123\"</summary>`

Manually converted to JSON:  
`{\"summary\":\"123\"}`

XML decoder copied from Bill’s first example:

```auto
decodeXml : String -> Xml.Value
decodeXml string =
   string
      |> Xml.Decode.decode
      |> Result.toMaybe
      |> Maybe.withDefault Xml.Encode.null

```

JSON decoder to extract the string:

```auto
import Json.Decode as JD

summaryDecoder : JD.Decoder String
summaryDecoder =
   JD.field "summary" JD.string

```

If I give the decoder the manually converted JSON:  
`JD.decodeString summaryDecoder "{\"summary\":\"123\"}"`  
I get the result `Ok "123"`

However, if I go via Xml:

`decodedXml = decodeXml "<summary>\"123\"</summary>"`  
_Debug.log:_

> `Object [Tag "summary" (Dict.fromList []) (StrNode "\"123\"")]`

- 

`decodedJSON = Xml.xmlToJson2 decodedXml`  
_Debug.log:_

> `<internals>`

- 

_Check_: `reEncodedXml = Xml.jsonToXml decodedJSON`  
_Debug.log:_

> `Tag "summary" (Dict.fromList []) (StrNode "\"123\"")`

- 

`summaryString = JD.decodeValue summaryDecoder decodedJSON`  
_Debug.log:_

> `Err (Failure "Expecting an OBJECT with a field named `summary`" <internals>)`

* * *

Notes:

1. A clue might be in the ‘Check’, where converting back to ‘XML’ does not apparently result in an Object.

2. Having re-read Bill’s documentation,

> The conversion of `Tag`s changed in version 2.0.0, so that they can be properly converted back. The attribute names become JSON keys with “@” prepended, and the value becomes a JSON key named “#value”: \<foo x=“x”\>1\</foo\> becomes {foo: {#value: 1, @x: “x”}}

I realized that  
`<summary>\"123\"</summary>`  
would instead become  
`{"summary": {"#value": "123", @x: null}}`

So I modified the converter to

```auto
summaryDecoder : JD.Decoder String
summaryDecoder =
   JD.field "summary" ( JD.field "#value" JD.string )

```

But, in the XML to JSON process above, I still get the error

> `Err (Failure "Expecting an OBJECT with a field named `summary`" <internals>)`

Using this new decoder, but with the ‘corrected’ JSON string given _directly_:  
`summaryStrHash = JD.decodeString summaryDecoder "{\"summary\":{\"#value\":\"123\"}}"`  
_Debug.log:_

> `Err (Field "summary" (Failure "Expecting an OBJECT with a field named `#value`" <internals>))`

So here it does now find the ‘summary’ field, but then fails to find the ‘#value’ field.

What am I doing wrong?  
Thanks

---

<div class="post-metadata">

### Author: ![lydell](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lydell/32/178_2.png) [@lydell](https://discourse.elm-lang.org/u/lydell)
#### Post date: [April 26, 2021, 4:08pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297/2 "2021-04-26T16:08:12Z")

</div>

`Xml.xmlToJson2` seems to create a JSON _array:_ `[{ "summary": "\"123\"" }]`

I figured this out by first converting the XML to JSON, and then turning that into a string using `Json.Encode.encode` so I could see what we’ve got to work with.

Play with it here: [https://ellie-app.com/cZWvzCV2f8ba1](https://ellie-app.com/cZWvzCV2f8ba1)

> So here it does now find the ‘summary’ field, but then fails to find the ‘#value’ field.

No, it doesn’t even try to look at the `"#value"` field since it fails earlier on finding `"summary"`.

---

<div class="post-metadata">

### Author: ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)
#### Post date: [April 30, 2021, 3:08pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297/3 "2021-04-30T15:08:07Z")

</div>

Thank you, @lydell, that was it!

So,

`summaryString = JD.decodeValue summaryDecoder decodedJSON`  
`Err (Failure "Expecting an OBJECT with a field named summary" <internals>)`

becomes

`summaryList = JD.decodeValue (JD.list summaryDecoder) decodedJSON`  
`Ok ["\"123\""]`

---

<div class="post-metadata">

### Author: ![choonkeat](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/choonkeat/32/1555_2.png) [@choonkeat](https://discourse.elm-lang.org/u/choonkeat)
#### Post date: [May 1, 2021, 2:14pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297/4 "2021-05-01T14:14:32Z")

</div>

> [@AlanQ](#):
>
> `decodedJSON = Xml.xmlToJson2 decodedXml`  
> _Debug.log:_
> 
> > `<internals>`

`<internals>` isn’t helpful and I need to debug json value often and actually have a function

```auto
debugJson : String -> Json.Encode.Value -> Json.Encode.Value
debugJson string value =
    let
        _ =
            Debug.log string (Json.Encode.encode 0 value)
    in
    value

```

so I can tag it to any value

```auto
decodedJSON =
    Xml.xmlToJson2 decodedXml
        |> debugJson "xmlToJson2"

```

---

<div class="post-metadata">

### Author: ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)
#### Post date: [May 2, 2021, 10:58pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297/5 "2021-05-02T22:58:48Z")

</div>

@choonkeat, that’s brilliant. Thank you.

```auto
debugJson : String -> JE.Value -> JE.Value
debugJson string value =
   let
      _ = Debug.log string (JE.encode 0 value)
   in
      value

```

```auto
decodedJSON =
   Xml.xmlToJson2 decodedXml
      |> debugJson "decodedJSON"

```

So,

The `debugJson` function is given

- a string to identify the `Debug.log` output
- the JSON Value.

The output of the function is just the JSON Value, so the Value passes through; it is unchanged by the function, and therefore doesn’t affect the code where it is inserted.

The clever stuff happens in the `let`:  
The calling of Debug.log generates debug output without assignment. But `let` must contain assignments. The underscore `_` could have been `x` or `y` or anything else. But, given that `_` is used in case statements to mean ‘_any value_’, presumably assigning the output of Debug.log to `_` is the equivalent of piping the output of a command line function to `/dev/null`.

Neat 🙂

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [May 12, 2021, 10:59pm UTC](https://discourse.elm-lang.org/t/error-converting-xml-to-json-and-extracting-values/7297/6 "2021-05-12T22:59:26Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
