Jsdom: ๊ตฌ๋ฌธ ๋ถ„์„๋œ XML ๋ฌธ์„œ์˜ XPath ์ฟผ๋ฆฌ๊ฐ€ ๋Œ€๋ฌธ์ž ์†์„ฑ์œผ๋กœ ์‹คํŒจํ•จ

์— ๋งŒ๋“  2019๋…„ 03์›” 12์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jsdom/jsdom

๊ธฐ๋ณธ ์ •๋ณด:

  • Node.js ๋ฒ„์ „: 8.9.1
  • jsdom ๋ฒ„์ „: 14.0.0

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 ์ฟผ๋ฆฌ๋Š” ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๋ฉฐ ๋Œ€๋ฌธ์ž๊ฐ€ ์žˆ๋Š” ์†์„ฑ์ด ์žˆ๋Š” ๋…ธ๋“œ์™€ ์ผ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋ชจ๋“  3 ๋Œ“๊ธ€

์šฐ๋ฆฌ๋Š” ์˜ค๋žœ ์‹œ๊ฐ„ ๋™์•ˆ ์ˆ˜๋™์œผ๋กœ ๊ตฌํ˜„ํ•œ ์˜ค๋ž˜๋œ xpath ๊ตฌํ˜„์„ ์œ ์ง€ ๊ด€๋ฆฌ๋˜๋Š” ํƒ€์‚ฌ ๊ตฌํ˜„์œผ๋กœ ๊ต์ฒดํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์„ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•œ ์ŠคํŒŸ ์ˆ˜์ • PR๋„ ํ—ˆ์šฉ๋˜์ง€๋งŒ ์ด๊ฒƒ์ด ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰