Fork me on GitHub
#specter
<
2018-02-18
>
Peter Wilkins22:02:01

Hi @nathanmarz and all. I'm stuck on a (probably) simple one. I have this xml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<book>
<frontmatter/>
<chapter name="Introduction">
    <para>Here is the intro</para>
    <para>Another paragraph</para>
</chapter>
<chapter name="Conclusion">
    <para>All done now</para>
</chapter>
</book>

Peter Wilkins22:02:29

the Challenge is to get the string content from chapter elements with attr name = "Introduction" ; using thread last

(time (->> [doc]
           (mapcat :content)
           (filter #(= :chapter (:tag %)))
           (filter #(= "Introduction" (get-in % [:attrs :name])))
           (mapcat :content)
           (filter #(= :para (:tag %)))
           (mapcat :content)
           (filter string?)))
; transducers and compose
(time (eduction
        (comp
          (mapcat :content)
          (filter (comp (partial = :chapter) :tag))
          (filter (comp (partial = "Introduction") :attrs :name))
          (mapcat :content)
          (filter (comp (partial = :para) :tag))
          (mapcat :content)
          (filter string?))
        [doc]))
; specter: this isn't correct yet...
(select [:content ALL
         (filterer :tag #(= % :chapter))
         (filterer :attrs :name #(= % "Introduction"))
         :content ALL
         (filterer :tag #(= % :para))
         :content ALL
         string?] doc)

nathanmarz23:02:59

@poppetew I think you're looking for selected? rather than filterer?

nathanmarz23:02:03

(select [:content
         ALL
         (selected? :tag (pred= :chapter))
         (selected? :attrs :name (pred= "Introduction"))
         :content
         ALL
         (selected? :tag (pred= :para))
         :content
         ALL
         string?]
  doc)

nathanmarz23:02:28

pred= is also slightly nicer than doing #(= % ...)