結論だけ先に言うと、バックスラッシュ2個でエスケープすればok。1個じゃなくて2個ね。
もくじ
Node.jsでHTML/XMLを扱うならとりあえずcheerio使っとくと楽
Node.jsでHTML/XMLを扱うなら、モジュール”Cheerio”を使うと、タグ名で指定した要素を簡単に取り出すことができてとっても便利です。
例えば、こういうxmlがあったとして
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <Product> <ns:Title>MacBook Pro 2017ver.</ns2:Title> <Price> <JPY>150,000</JPY> <US$>140</US$> </Price> <SalesRank>1</SalesRank> </Product> |
シェルからnodeを起動し、cheerioモジュールを使っていろいろイジってみます。
まずは以下のようにcheerio.load()メソッドを使って対象のxmlを定数$にロードしてやると…
const xml = <上記のxml>
const $ = cheerio.load(xml);
$(‘セレクタ名’)
って感じで、jQueryライクにセレクタで要素を指定してデータを取り出すことができる。
例えば、上記のxmlからSalesRankノードのテキストを取り出すなら、
‘1’
こんな感じで書いてやれば、ノード内のテキストである”1″が返る。
タグ名に記号が入ってたら、エスケープしなきゃなんだけど…
ただ、タグ名に”$”とか”:”みたいな文字が入っていた場合、そのまま指定するとエラーになってしまう。
例えば、上のxmlでns:Titleノードを指定しようとした場合、以下のようにセレクタにノード名をそのまま書くとNG。
SyntaxError: unmatched pseudo-class :title
:titleだと?そんな疑似クラスねえよ!的なエラーが出て叱られる。
はじめにこのエラーを見たときは、「ほーん。ほなバックスラッシュ一発でエスケープすりゃええんやろ」くらいのことを考えていたのだが
SyntaxError: unmatched pseudo-class :title
だから!:titleなんてねえんだよ!的なエラーが再び。
あれ?エスケープ効かないの??とちょっと混乱したのでググってみた。
解決策:バックスラッシュ2個でエスケープすればおk
すると、フツーに公式のGIthubにissueが上がってた。
SyntaxError: unmatched pseudo-class :foo
Q: Trying to use cheerio to match against a custom HTML node receives that error.
A: double backslash fixed it. I originally tried one but not two, smh.
Q:HTMLでCheerio使ってノードを取り出そうとしたら、こんなエラー出たんだけど
A:それ俺もやったわ。バックスラッシュ2個でエスケープすれば直るよ。1個じゃなくて2個な。やれやれ。
バックスラッシュ2個なのかよ!
というわけで、言われたとーりバックスラッシュ2個にしてみる。
‘MacBook Pro 2017ver. 150,000 140 1’
できた。
他の文字でも同様に、バックスラッシュ2発でエスケープ。
‘140’
感想とか
最近、ブログがすっかり僕の出したエラーログになってる感がありますねー。
まーもし同様のことでハマってる方のお役に立てば嬉しいので、今後もちまちまメモり続けようと思います。
あと、今回ブログ用に調べてて初めて知ったんですけど、バックスラッシュ2発でのエスケープってjQueryではフツーに常識だったみたいですね。cheerioでも同様ということで。
参考にしたサイト
cheeriojs/cheerio – issues – Github
https://github.com/cheeriojs/cheerio/issues/697
Cheerio
https://cheerio.js.org/
jQueryセレクタのエスケープ – Qiita
http://qiita.com/mk_summer/items/6eb745c7babf2abfc03c