Backend, Javascript

Node.jsでDOMを触る

XMLをNode.jsで触りたかったのでDOMParserを使おうとしたら嵌まったので、サンプルを残す。

Node.jsはブラウザと違って DOMParser がないので、tsconfigdomをライブラリに加えてトランスパイルできたとしても、実行しようとするとエラーになる。

var parser = new DOMParser();
             ^
ReferenceError: DOMParser is not defined

そこで使うのが、「Trying to use the DOMParser with node js」で紹介されているjsdomというモジュール。ブラウザと比べると使い勝手が若干違って、JSDOMをインスタンス化してからDOMParserをインスタンス化しないといけない。

import { readFileSync } from 'fs';
import { JSDOM } from 'jsdom';
const xml = readFileSync( './sample.xml', { encoding: 'utf-8' } );

const jsdom = new JSDOM();
const parser = new jsdom.window.DOMParser();
const dom = parser.parseFromString( xml, 'application/xhtml+xml' );

const addressList = dom.querySelectorAll( 'Address' );
const res: string[] = [];

for( let i=0; i<addressList.length; i++ ) {
  res.push( addressList.item(i).getAttribute( 'Type' ) );
}

console.log( res );

querySelectorAllの戻り値はNodeListOf<T>で、通常はインデックスでループする。tsconfigdownlevelIterationを有効化して、DOM.Iterableライブラリを使用すると、for ofでループできるようになる。

{
  "compilerOptions": {
    "downlevelIteration": true,
    "lib": [
      "dom",
      "DOM.Iterable"
    ]
  }
}

DOM.Iterableを有効化して for ofループに書き換えたら以下のようになる。

import { readFileSync } from 'fs';
import { JSDOM } from 'jsdom';
const xml = readFileSync( './sample.xml', { encoding: 'utf-8' } );

const jsdom = new JSDOM();
const parser = new jsdom.window.DOMParser();
const dom = parser.parseFromString( xml, 'application/xhtml+xml' );


const addressList = dom.querySelectorAll( 'Address' );
const res: string[] = [];

for( let address of addressList ) {
  res.push( address.getAttribute('Type') );
}

console.log( res );

コメントを残す