1

xml ファイルがあるとします。

            <span id="assignee-val">

        <span class="user-hover" id="issue_summary_assignee_m" rel="m">
        <span class="aui-avatar aui-avatar-small"><div class="aui-avatar-inner"><img src="/secure/useravatar?size=small&amp;avatarId=10222" /></div></span>
        This Value!
    </span>
</span>

問題は"This Value!"、この xml から抜け出す方法です。

これは私が持っているものです:(

> :m + Control.Applicative Data.ByteString.Lazy Text.HTML.DOM Text.XML.Cursor
> Prelude.map content . (element "span" >=> "id" `attributeIs` "assignee-val" >=> child >=> element "span" >=> "class" `attributeIs` "user-hover" >=> child) . fromDocument . parseLBS <$> Data.ByteString.Lazy.readFile "xmlfile" 
[["\n            "],[],["\n            This Value!\n        "]]
  1. なぜ3つの答えがあるのですか?<span class="user-hover">タグ内のコンテンツをより正確に定義するクエリはどれですか?
  2. スペースのインデントと改行記号を自動的に削除する方法は?

UPD : つまり、問題は、ネストされたタグをすべて削除し (いくつあるかは関係ありません)、最初のレベルのコンテンツのみを取得する方法です"This Value!"(およびスペースと改行)。

4

2 に答える 2

2

質問 1 - なぜ 3 つの答えがあるのですか?

ナビゲートしたデータには、「user-hover」span タグの子が保持されています。重要でないものを引き出すと、ノードは次のようになります。

<span class="user-hover">
    <span />
    This Value!
</span>

XML パーサーはこれを次のように認識します。

<span class="user-hover">[TextNode "\n    "]<span />[TextNode "\n    This Value!\n"]</span>

したがって、「user-hover」要素には実際には 3 つの子要素があります。

[TextNode "\n    ", <span />, TextNode "\n    This Value!\n"]

次に、これらの値のそれぞれに「コンテンツ」を適用します。span 要素には内部コンテンツがないため、"" が返され、次のようになります。

[["\n    "], [], ["\n    This Value!\n"]]

質問 2- スペースのインデントと改行記号を自動的に削除するにはどうすればよいですか?

xml 仕様によると、xml パーサーはスペースを保持する必要があります。XML カーソル ライブラリには、このスペースを削除するためのツールが含まれている可能性があります (一部の xml 処理ライブラリでは、処理後の空白スペースの自動削除を有効にするオプションが提供されています)。クエリの後の別の呼び出しで空白を取り除くだけです。

関数を使用Data.Text.stripして、空白の除去を行うことができます。


必要な値を取得するには、クエリにさらに情報が必要です..データは常に「ユーザーホバー」スパン要素の3番目の位置にありますか? それは常に<span class="aui-avatar aui-avatar-small" />要素の後にありますか?user-hover 要素内のすべてのコンテンツが連結され、スペースが取り除かれますか? これに答えれば、解決策は明らかです。


更新された回答-

あなたが提供した追加情報を使用して、回答にさらに情報を追加できます。

簡単な答えは、"Prelude.map コンテンツ" を削除し、パイプラインに ">=> コンテンツ" を追加Data.Text.concatしてから、最終出力にもう 1 つ追加することです。

理由の詳細はこちら....

Text.XML.Cursor のほとんどすべての関数は、a->[a]各フィルターをノードのリストに適用し、結果を連結するという形式です。これは、XPath で発生することと非常によく似ており、明らかにその後にモデル化されています。

良いことに、今説明したパターンは配列モナドの動作とまったく同じです.. a->[a]bind を使用して一連の関数をチェーンする(>>=)と、パイプラインは基本的にパイプラインのconcat . map f各ステージに対して a を実行します。を前に追加すると機能しましたmap contentが、ライブラリが完全な XPath のようなツールで実行することを意図した意図したジョブの半分しか実行しませんでした。テキストコンテンツを引き出しましたが、結果を連結しませんでした。このように使用するとcontent、要素内のテキスト ノード内のテキストのみのリストが返されます。これらのテキスト項目を結合するには、最後の連結が 1 つ必要です。

パイプラインを使用した場合:

Data.Text.concat . (child >=> element "span" >=> "id" `attributeIs` "assignee-val" >=> child >=> element "span" >=> "class" `attributeIs` "user-hover" >=> child >=> content) . fromDocument . parseLBS <$> Data.ByteString.Lazy.readFile "file.xml" 

結果が出ました

"\n        \n        This Value!\n    "

必要に応じて、最終結果を Data.Text.strip で削除することもできます....

于 2013-12-15T21:16:47.993 に答える