Last active
July 11, 2019 11:53
-
-
Save bag-man/6b21122c1466a7fab639002a8f24e5d7 to your computer and use it in GitHub Desktop.
A class wrapper around libxmljs, for reading values with XML namespaces
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Document, Element, parseXml } from 'libxmljs'; | |
import { VError } from 'verror'; | |
export class XMLReader { | |
private document: Document; | |
private namespaces: Record<string, string>; | |
constructor(inputXml: string) { | |
try { | |
this.document = parseXml(inputXml); | |
this.namespaces = {}; | |
// Bad typings? No .namespaces() | |
for (const ns of (this.document as any).namespaces()) { | |
let name = ns.prefix(); | |
if (name === null) { | |
name = '_'; | |
} | |
this.namespaces[name] = ns.href(); | |
} | |
} catch (cause) { | |
throw new VError( | |
{ cause, name: 'ParseError', info: { inputXml } }, | |
'Failed to parse XML', | |
); | |
} | |
} | |
public get(xpath: string): string { | |
const element: Element | null = this.document.get(xpath, this.namespaces); | |
if (element === null || element === undefined) { | |
throw new Error(`XPath element "${xpath}" was not found`); | |
} | |
return element.text(); | |
} | |
} | |
const input: string = `<?xml version="1.0" encoding="UTF-8"?> | |
<root xmlns="default:namespace" xmlns:opt="inner:namespace"> | |
<outer><opt:inner>value</opt:inner></outer> | |
</root> | |
`; | |
const xml = new XMLReader(input); | |
// Need to specify the default namespace with _. | |
console.log(xml.get('/_:root/_:outer/opt:inner')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment