我想使用 XSLT 将未知数量的不同但非常相似的结构化输入 XML 文档转换为单个输出 XML 格式。 我的平台是 node.js,因此我正在研究 saxon-js 以实现该目标。
我现在的问题是: XSLT 可以做到这一点吗? 我是否可以参数化 XSLT,以根据输入 XML 获取不同的 XPath 表达式(我无法以任何方式更改该表达式)? 我正在寻找一种添加 XPath 表达式作为参数的方法,但我找不到任何类型来创建它们。
输入 XML 示例:
<format1>
<some_id>4d736817-ebc1-42d3-be3f-4dda7178d1aa</some_id>
<the_uri>https://example.com</the_uri>
</format1>
<format2>
<also_the_id>9dac9085-99b3-4d52-aa56-fa59fc41e066</also_the_id>
<url_field>https://example2.com</url_field>
</format2>
所需的输出 XML:
<myXml>
<provider>provider1</provider>
<id>4d736817-ebc1-42d3-be3f-4dda7178d1aa</id>
<url>https://example.com</url>
</myXml>
XSLT(
xsltString
):
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="providerId" />
<xsl:param name="xpathId" />
<xsl:param name="xpathUrl" />
<xsl:template match="/">
<myXml>
<provider>
<xsl:value-of select="$providerId" />
</provider>
<id>
<xsl:value-of select="$xpathId"/>
</id>
<url>
<xsl:value-of select="$xpathUrl"/>
</url>
</myXml>
</xsl:template>
</xsl:stylesheet>
node.js 代码(
inputXml
是上面的“format1”xml):
const inputXmlDoc = await SaxonJS.getResource({
text: inputXml,
type: "xml",
});
const outputXml = SaxonJS.XPath.evaluate(
`transform(map {
'stylesheet-text': $xslt,
'stylesheet-params': map {
QName('', 'providerId'): $providerId,
QName('', 'xpathId'): '$xpathId',
QName('', 'xpathUrl'): '$xpathUrl',
},
'source-node': .,
'delivery-format': 'serialized'
})?output`,
inputXmlDoc,
{
params: {
xslt: xsltString,
providerId: 'some-provider-id',
xpathId: '/format1/some_id'
xpathUrl: '/format1/the_uri'
},
},
);
输出xml(错误):
<myXml>
<provider>some-provider-id</provider>
<id>/format1/some_id</id>
<url>/format1/the_uri</url>
</myXml>
此代码不起作用,因为 XPath 表达式不是字符串。它适用于providerId,它只是一个字符串。所以我只得到 XPath 表达式而不是解析值。 我的目标是仅更改参数映射以考虑不同的输入 XML,重用相同的 XSLT 文档并获得相同的输出 XML 格式。
我认为你可以使用静态参数和阴影属性
_select="{$xpathId}"
。