如何在 Node 中使用 saxon-js 处理 XPath 表达式

Posted

技术标签:

【中文标题】如何在 Node 中使用 saxon-js 处理 XPath 表达式【英文标题】:How to handle XPath expressions with saxon-js in Node 【发布时间】:2021-08-30 21:11:14 【问题描述】:

我在 Typescript 中编写了以下类:

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-Expression 在这种测试数据上是有效的,所以我假设我必须以另一种方式提供表达式:

<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>

我做错了什么,谢谢。

【问题讨论】:

【参考方案1】:

SaxonJS.getResource() 是异步的,返回一个 Promise;我认为您已将此 Promise 提供给 SaxonJS.XPath.Evaluate(),它会将其视为通用 javascript 对象。

你需要类似的东西

saxon.getResource(
            file: sourceFile,
            type: "xml"
        )
.then((doc) => saxon.XPath.evaluate(xpathQuery, doc))

当然,如果您不希望整个事情都是异步的,则不必使用 saxon.getResource() - doc 只是一个 DOM 文档节点,您可以按照自己喜欢的方式创建它。

【讨论】:

以上是关于如何在 Node 中使用 saxon-js 处理 XPath 表达式的主要内容,如果未能解决你的问题,请参考以下文章

在 node.js 中评估 xpath2.0

Saxon-JS 处理包含元素的 CDATA 是不是存在已知错误

如何将xsl文件转换为sef文件

如何通过 Saxon-JS 调整图像大小?

使用 Saxon-JS 及其全局 Javascript 函数命名空间在 XSL 中调用 jQuery-UI 组件?

无法将 Saxon-JS 2 与 Webpack 一起使用