Jeśli mam dane XML, które próbuję przekształcić w Elm Html, czy istnieje sposób na przejście po drzewie XML w poszukiwaniu elementu, który mógłby znajdować się w dowolnym miejscu w tym drzewie? Na przykład chciałbym wziąć ten przychodzący plik XML:

<root>
  <arbitrary>
    <numberOfTagsHere>
      <p>Lorem ipsum text goes here. May contain <tag foo="bar">some text</tag></p>
      <p>Maybe another paragraph here.</p>
    </numberOfTagsHere>
  </arbitrary>
</root>

I zrób coś takiego:

<html>
  <div class="arbitrary">
  <div class="numberOfTagsHere">
    <p>Lorem ipsum text goes here. May contain <span class="foo bar">some text</span></p>
    <p>Maybe another paragraph here.</p>
  </div>
  </div>
</html>

Czy to wykracza poza zakres Elm? Czy powinienem zamiast tego przejść na XSLT?

Widzę, że istnieją biblioteki analizujące XML, takie jak ten a>, ale tak naprawdę nie widzę sposobu na chodzenie po drzewie, przekształcanie znaczników po drodze.

0
Jonathan 9 listopad 2019, 02:10
Na pewno można chodzić po drzewie. Potrzebujesz definicji drzewa, na przykład struktury rekordów, a następnie musisz zdecydować, co zrobić z każdym węzłem, gdy go znajdziesz. Co masz do tej pory?
 – 
Bob Dalgleish
14 listopad 2019, 02:18

1 odpowiedź

Biblioteka, o której wspomniałeś, jest dekoderem, ale sugerowałbym użycie tutaj bazowego parsera.

Możesz użyć elm/parser do zbudowania własnego parsera, który wyprowadza drzewo, które możesz łatwo przejść i wypisać albo Html lub ciąg reprezentujący html. Alternatywnie możesz użyć już zbudowanego dla Ciebie.

https://github.com/jinjor/elm-xml-parser jest dobrym opcja. Wierzę, że jest używany przez pakiet elm-xml-decode, o którym wspomniałeś wewnętrznie.

Oto przykład tego, jak możesz poprosić Elm'a o pobranie ciągu html i wyświetlenie własnej wersji HTML Elma za pomocą jinjor / elm-xml-parser (w szczególności funkcja xmlToHtml pokazuje, jak możesz „zejść po drzewie” który jest wyprowadzany przez XmlParser):

import Html as H
import XmlParser

xmlToHtml : XmlParser.Node -> H.Html Never
xmlToHtml xmlNode =
    case xmlNode of
        XmlParser.Element tag attributes children ->
            -- do any mapping of the xml tag or attribute to what you want here!
            H.node tag [] (List.map xmlToHtml children)

        XmlParser.Text text ->
            H.text text


view : Model -> H.Html Never
view _ =
    let
        xml =
            """
            <arbitrary>
              <numberOfTagsHere>
                <p>Lorem ipsum text goes here. May contain <tag foo="bar">some text</tag></p>
                <p>Maybe another paragraph here.</p>
              </numberOfTagsHere>
            </arbitrary>
            """
    in
    Result.map
        (.root >> xmlToHtml)
        (XmlParser.parse xml)
        |> Result.withDefault (H.text "  Failed to parse the xml :(  ")
0
Tony 14 listopad 2019, 20:45
To jest świetne. Ale jak mogę zaimportować model? Próbuję uruchomić go tutaj w Ellie: ellie-app.com/7cyJrjYFyqRa1 i narzeka, że nie może znaleźć tego typu.
 – 
Jonathan
14 listopad 2019, 22:37
Model to dowolny typ, którego używa Twoja aplikacja. Sam to deklarujesz. Oto działający przykład Twojej Ellie ze wszystkim, co działa: ellie-app.com/7cyXF9vXzHra1
 – 
Tony
14 listopad 2019, 22:54