如何在 Node 中使用 saxon-js 处理 XPath 表达式
How to handle XPath expressions with saxon-js in Node
我用 Typescript 写了以下 class:
import * as saxon from 'saxon-js';
export class XsltXpath {
private static readonly SINGLETON: XsltXpath = new XsltXpath();
static transform(styleSheetFile: string, sourceFile: string): any {
return XsltXpath.SINGLETON.transformViaXsl(styleSheetFile, sourceFile);
}
static pick(sourceFile: string, xpathQuery: string): any {
return XsltXpath.SINGLETON.pickViaXpath(sourceFile, xpathQuery);
}
private async transformViaXsl(styleSheetFile: string, sourceFile: string): Promise<any> {
const output: { principalResult: any; } = await saxon.transform({
stylesheetFileName: styleSheetFile,
sourceFileName: sourceFile,
destination: 'serialized'
}, 'async');
return output.principalResult;
}
private pickViaXpath(sourceFile: string, xpathQuery: string): any {
const doc = saxon.getResource({
file: sourceFile,
type: "xml"
});
const result = saxon.XPath.evaluate(xpathQuery, doc);
const output = saxon.serialize(result, { method: 'xml', indent: true, 'omit-xml-declaration': true });
console.log(output);
return output;
}
}
...我是这样使用它的:
const output: any = await XsltXpath.transform('./testdata/stylesheet.sef.json', './testdata/data.xml');
console.log('OUTPUT: ', output);
res.send(output);
OR
const output: any = await XsltXpath.pick('./testdata/data.xml', 'catalog/cd//artist');
console.log('OUTPUT: ', output);
res.send(output);
“transform”-Method 工作正常,但是当我使用“pick”-Method 时,我总是得到这个错误:
message: 'Context item for child axis is not a node - supplied:HashTrie map{}',
name: 'XError',
code: 'XPTY0020'
我的 XPath 表达式在这种测试数据上是有效的,所以我假设我必须以另一种方式提供表达式:
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
...
</catalog>
我做错了什么,谢谢。
SaxonJS.getResource()
是异步的,returns 是 Promise;我认为您已将此 Promise 提供给 SaxonJS.XPath.Evaluate()
,它将其视为一般 Javascript 对象。
你需要这样的东西
saxon.getResource({
file: sourceFile,
type: "xml"
})
.then((doc) => saxon.XPath.evaluate(xpathQuery, doc))
当然如果你不希望整个事情是异步的,你不必使用 saxon.getResource() - doc 只是一个 DOM 文档节点,你可以随心所欲地创造。
我用 Typescript 写了以下 class:
import * as saxon from 'saxon-js';
export class XsltXpath {
private static readonly SINGLETON: XsltXpath = new XsltXpath();
static transform(styleSheetFile: string, sourceFile: string): any {
return XsltXpath.SINGLETON.transformViaXsl(styleSheetFile, sourceFile);
}
static pick(sourceFile: string, xpathQuery: string): any {
return XsltXpath.SINGLETON.pickViaXpath(sourceFile, xpathQuery);
}
private async transformViaXsl(styleSheetFile: string, sourceFile: string): Promise<any> {
const output: { principalResult: any; } = await saxon.transform({
stylesheetFileName: styleSheetFile,
sourceFileName: sourceFile,
destination: 'serialized'
}, 'async');
return output.principalResult;
}
private pickViaXpath(sourceFile: string, xpathQuery: string): any {
const doc = saxon.getResource({
file: sourceFile,
type: "xml"
});
const result = saxon.XPath.evaluate(xpathQuery, doc);
const output = saxon.serialize(result, { method: 'xml', indent: true, 'omit-xml-declaration': true });
console.log(output);
return output;
}
}
...我是这样使用它的:
const output: any = await XsltXpath.transform('./testdata/stylesheet.sef.json', './testdata/data.xml');
console.log('OUTPUT: ', output);
res.send(output);
OR
const output: any = await XsltXpath.pick('./testdata/data.xml', 'catalog/cd//artist');
console.log('OUTPUT: ', output);
res.send(output);
“transform”-Method 工作正常,但是当我使用“pick”-Method 时,我总是得到这个错误:
message: 'Context item for child axis is not a node - supplied:HashTrie map{}',
name: 'XError',
code: 'XPTY0020'
我的 XPath 表达式在这种测试数据上是有效的,所以我假设我必须以另一种方式提供表达式:
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
...
</catalog>
我做错了什么,谢谢。
SaxonJS.getResource()
是异步的,returns 是 Promise;我认为您已将此 Promise 提供给 SaxonJS.XPath.Evaluate()
,它将其视为一般 Javascript 对象。
你需要这样的东西
saxon.getResource({
file: sourceFile,
type: "xml"
})
.then((doc) => saxon.XPath.evaluate(xpathQuery, doc))
当然如果你不希望整个事情是异步的,你不必使用 saxon.getResource() - doc 只是一个 DOM 文档节点,你可以随心所欲地创造。