XPath๋ฅผ ์ฌ์ฉํ์ฌ JSDOM์ DOMParser์ ์ํด ์์ฑ๋ XML ๋ฌธ์๋ฅผ ์ฟผ๋ฆฌ/ํ๊ฐํ ๋ ์ฟผ๋ฆฌ์ ์์ฑ ๋ถ๋ถ์ด ์๋ฌธ์๋ก ๊ฐ์ ๋ณํ๋์ด ๋๋ฌธ์๊ฐ ํฌํจ๋ ์์ฑ์ ์ฟผ๋ฆฌํ ์ ์๊ฒ ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด ๋ค์ ๋ฌธ์๊ฐ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
<?xml version="1.0" encoding="utf-8"?><example Foo="bar"></example>
^-- capital F
//*[@Foo="bar"]
(๋๋ ํด๋น ๋ฌธ์ ์ ๊ฒฝ์ฐ //*[@foo="bar"]
๋ํ ์ฟผ๋ฆฌ๋ ์ผ์น ํญ๋ชฉ์ ๋ฐํํ์ง ์์ง๋ง ์ด ๋ฌธ์๋ ์๋ฌธ์ ์์ฑ์ ๋์ ์ฌ์ฉํฉ๋๋ค.
<?xml version="1.0" encoding="utf-8"?><example foo="bar"></example>
^-- lower case F
์ด์ ์ด ์ ๋ฌธ์๋ฅผ ์ฌ์ฉํ์ฌ //*[@foo="bar"]
( ๋ฐ ๋๋ฌธ์ //*[@Foo="bar"]
)๊ฐ ์ผ์น ํญ๋ชฉ์ ์ฑ๊ณต์ ์ผ๋ก ์ฐพ์ต๋๋ค.
๋๋ ์ค๋์ ์ ๋น์ทํ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค(https://github.com/jsdom/jsdom/issues/651). ์ด ๋ฌธ์ ๋ Saxes๋ฅผ ๋์ ํ์ฌ HTML ๋ฌธ์์ ๋ณ๋๋ก XML ๋ฌธ์๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ์ง๋ง ํ์ฌ๋ ๋ชจ๋ ๊ตฌ๋ฌธ ๋ถ์ ์์ค์ ์์ต๋๋ค. ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ๋ฌธ ๋ถ์๋ ๊ฒ ๊ฐ์ต๋๋ค(์: ์์ฑ์ด ๋์๋ฌธ์๋ฅผ ์ ์งํจ). ์ฟผ๋ฆฌ๊ฐ ์๋ฌธ์๋ก ํ์๋๋ ๊ฒ์ XPath ํ๊ฐ ์์ค์ ๋๋ค.
์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ ์์น๋ฅผ ์ขํ๋ ค๊ณ ์๋ํ์ผ๋ฉฐ https://github.com/jsdom/jsdom/blob/b83783da63deeb7c5602b024a92e214df423a412/lib/jsdom/level3/xpath.js#L1659์ ๋๋ฌํ์ต๋๋ค.
shouldLowerCase
๊ฐ์ false
๋ก ์ค์ ํ๋ฉด ๋ด ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ ๋์ง๋ง ๋๋จธ์ง XPath ๊ตฌํ์ ์ด๋ค ์ํฅ์ ๋ฏธ์น๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
const { JSDOM } = require("jsdom");
const dom = new JSDOM();
const domParser = new dom.window.DOMParser();
const doc = domParser.parseFromString('<?xml version="1.0" encoding="utf-8"?><example Foo="bar"></example>', 'text/xml');
const result = doc.evaluate('//*[@Foo="bar"]', doc, null, XPathResult.ANY_TYPE, null);
const exampleNode = result.iterateNext();
console.log('Result:', exampleNode); // exampleNode is null
https://jsbin.com/qegifaqumi/2/edit?js ,์ฝ์
XPath ์ฟผ๋ฆฌ๋ ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ๋ฉฐ ๋๋ฌธ์๊ฐ ์๋ ์์ฑ์ด ์๋ ๋ ธ๋์ ์ผ์นํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์ค๋ ์๊ฐ ๋์ ์๋์ผ๋ก ๊ตฌํํ ์ค๋๋ xpath ๊ตฌํ์ ์ ์ง ๊ด๋ฆฌ๋๋ ํ์ฌ ๊ตฌํ์ผ๋ก ๊ต์ฒดํด์ผ ํ๋ ์์ ์ ํด์์ต๋๋ค. ํ ์คํธ๋ฅผ ํตํ ์คํ ์์ PR๋ ํ์ฉ๋์ง๋ง ์ด๊ฒ์ด ๋ฌธ์ ๋ฅผ ์์ ํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ผ ๊ฒ์ ๋๋ค.
์๋ ํ์ธ์, ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
https://mobile.twitter.com/slicknet/status/782274190451671040