【问题标题】:How to process an XMLDocument using EXSLT or XSL 2 in Swift?如何在 Swift 中使用 EXSLT 或 XSL 2 处理 XMLDocument?
【发布时间】:2017-02-11 14:13:02
【问题描述】:

我的 Swift 应用程序生成一个 XMLDocument,然后使用 XSLT 对其进行转换:

xmlDocument.object(byApplyingXSLTString: xsltString, arguments: nil)

在我的 XSLT 样式表 (xsltString) 中,我想使用 XPath 访问结果树片段。这在 XSLT 1.0 中不受支持;我尝试使用 XSLT 2.0,但 Swift 似乎不支持它;在 xsl:stylesheet 元素中指定 version="2.0" 会产生此错误:

xsl:version: only 1.0 features are supported


我想我可以使用 EXSLT 中的node-set。我对此并不熟悉,但我尝试将有关 EXSLT 的信息添加到 xsl:stylesheet 元素。这似乎没有效果:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:exsl="http://exslt.org/common"
     extension-element-prefixes="exsl"
     version="1.0">

我收到以下错误:

xmlXPathCompOpEval: function node-set not found
XPath error : Unregistered function


在我的情况下是否可以使用 XSL 2.0 或 EXSLT?如何使用?

【问题讨论】:

  • 考虑向我们展示您尝试过的最小但完整的示例。 XSLT 1.0 处理器不支持exsl:node-set 或专有名称空间中的类似功能是相当不寻常的。因此,找出 Swift 使用的 XSLT 处理器,希望有一种方法可以将结果树片段转换为节点集。
  • 尝试在你的处理器上运行一个简单的测试用例,比如xsltransform.net/3NSSEvF 的样式表。
  • 谢谢。使用您链接到的样式表,我看到 Swift 正在使用 libxslt。但是,我无法更进一步:我尝试在 node-set 前加上 libxslt:xt:saxon:,如文档中的 here 所述,但总是得到相同的错误:xmlXPathCompOpEval: function node-set not found
  • 那么 Swift 使用 function-available('exsl:node-set') 检查的示例样式表输出了什么?
  • 该结果确实表明 Swift 使用了 libxslt,但不支持 exsl:node-set。因此,除非您也可以从 Swift 作为外部程序调用 xsltproc/libxslt(支持 EXSLT),否则听起来好像确实没有办法执行带有exsl:node-set 的 XSLT 1.0。

标签: xml swift exslt


【解决方案1】:

Martin Honnen 的建议让我考虑使用 xsltproc,而不是使用 Swift 的 object(byApplyingXSLTString:arguments:) 方法。

这是结果的样子。

Swift 代码

// Write XML to temporary file
xmlDocument.xmlString.write(to: temporaryXMLFileURL, atomically: false, encoding: String.Encoding.utf8)

// Use xsltproc to apply the XSLT transformation
let task = Process()
task.launchPath = "/usr/bin/xsltproc"
task.arguments = try [xsltFileURL.absoluteString, temporaryXMLFileURL.absoluteString]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let xsltResult = String(data: data, encoding: .utf8)!

XSLT 代码

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exslt="http://exslt.org/common"
    extension-element-prefixes="exslt"
    version="1.0">

    <xsl:variable name="stuff">
        ...
    </xsl:variable>

    <xsl:for-each select="exslt:node-set($stuff)/stuff">
        ...
    </xsl:for-each>

</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多