I'm trying to get the first <bar>
's text node with xml-lens from an XML like this:
<foo>
<bar>
I want ONLY this!
</bar>
<bar>
I DON'T want this!
</bar>
</foo>
In other words, I want to write a lens expression equivalent with XPath /foo/bar[1]/text()
First, I wrote a haskell script like below:
{-# LANGUAGE OverloadedStrings #-}
import Control.Lens
import Text.XML.Lens
import Text.HTML.DOM
import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy.IO as TIO
main :: IO ()
main = do
input <- TIO.getContents
parseLT input & toListOf (root . el "foo" ./ indexing (el "bar") . index 0 . text) & map T.fromStrict & T.unlines & TIO.putStr
But Actually got both first and second <bar>
's texts:
> stack runghc sample.hs < input.xml
I want ONLY this!
I DON'T want this!
Isn't this possible with current xml-lens implementation? Should I submit an issue to xml-lens or some other project?
This is correct behavior.
indexing
assigns indices to targets of a traversal; el
has at most one target so only 0 will be given.
You may want to use el "foo" . indexing (plate . el "bar") . index 0
or el "foo" . elementOf (plate . el "bar") 0
instead. These handle multiple occurrences of "bar"
.