5

私はXMLファイルを解析してHXTおり、ノード抽出の一部をモジュラーピースに分割しようとしています(これをガイドとして使用しています)。残念ながら、最初のレベルの解析を行うと、一部のセレクターを適用する方法がわかりません。

 import Text.XML.HXT.Core

 let node tag = multi (hasName tag)
 xml <- readFile "test.xml"
 let doc = readString [withValidate yes, withParseHTML no, withWarnings no] xml
 books <- runX $ doc >>> node "book"

本にはタイプがあることがわかりました[XmlTree]

 :t books
 books :: [XmlTree]

books次に、サブツリー内の最初の要素を取得して、いくつかの値を抽出したいと思います。

 let b = head(books)
 runX $ b >>> node "cost"

Couldn't match type ‘Data.Tree.NTree.TypeDefs.NTree’
               with ‘IOSLA (XIOState ()) XmlTree’
Expected type: IOSLA (XIOState ()) XmlTree XNode
  Actual type: XmlTree
In the first argument of ‘(>>>)’, namely ‘b’
In the second argument of ‘($)’, namely ‘b >>> node "cost"’

一度セレクターを見つけることができず、XmlTree何をしたいのかを説明するために上記の誤った使用法を示しています。私はこれができることを知っています:

 runX $ doc >>> node "book" >>> node "cost" /> getText
 ["55.9","95.0"]

しかし、私は興味があるだけでcostなく、内部のより多くの要素にも興味がありbookます。XML ファイルはかなり深いので、すべてを入れ子にしたくありません。<+>多くの評価者は、必要なチャンクを抽出してから、別の関数でサブ要素を抽出することを好みます。

例 (作成) XML ファイル:

 <?xml version="1.0" encoding="UTF-8"?><start xmlns="http://www.example.com/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <books> 
         <book>
             <author>
                 <name>
                     <first>Joe</first>
                     <last>Smith</last>
                 </name>
                 <city>New York City</city>
             </author>
             <released>1990-11-15</released>
             <isbn>1234567890</isbn>
             <publisher>X Publisher</publisher>
             <cost>55.9</cost>
         </book>
         <book>
             <author>
                 <name>
                     <first>Jane</first>
                     <last>Jones</last>
                 </name>
                 <city>San Francisco</city>
             </author>
             <released>1999-01-19</released>
             <isbn>0987654321</isbn>
             <publisher>Y Publisher</publisher>
             <cost>95.0</cost>
         </book>
     </books>
  </start> 

のサブ要素を抽出する方法を誰かが理解するのを手伝ってくれますかbook? >>>理想的には、と同じくらい素晴らしいものを使用して、それぞれが大まかに署名を持つ、などのnode独自の関数を定義できますgetCostgetNameXmlTree -> [String]

4

1 に答える 1

3

docあなたが思っていたものではありません。タイプがありIOStateArrow s b XmlTreeます。ガイドをもう一度読む必要があります。知りたいことは、タイトル「Avoiding IO」の下にまとめられています。

矢印は基本的に関数です。SomeArrow a bタイプ の一般化/特殊化された関数と見なすことができますa -> b>>>スコープ内の他の演算子は、関数合成と同様に、アロー合成用です。booksタイプ[XmlTree]があるため、矢印ではなく、矢印で構成することはできません。あなたのニーズを満たすのはrunLA、矢印node "tag"を通常の関数のように変換することです:

module Main where

import           Text.XML.HXT.Core

main = do
  html <- readFile "test.xml"
  let doc = readString [withValidate yes, withParseHTML no, withWarnings no] html
  books <- runX $ doc >>> node "book"
  -- runLA (node "cost" /> getText) :: XmlTree -> [String]
  let costs = books >>= runLA (node "cost" /> getText)
  print costs

node tag = multi (hasName tag)
于 2016-01-25T12:26:57.003 に答える