如何在转换中使用 xml csv-parser 包? (命名空间给出无效的 obj ref)

Posted

技术标签:

【中文标题】如何在转换中使用 xml csv-parser 包? (命名空间给出无效的 obj ref)【英文标题】:How to use the xml csv-parser package in a transform? (namespace give invalid obj ref) 【发布时间】:2020-05-24 11:11:01 【问题描述】:

我需要将 CSV 转换为 XML。

我想用 xslt 一步完成。

我对@9​​87654321@ 非常感兴趣。该文档显示了一个声明

命名空间的示例
xmlns:csv="http://example.com/csv"

在文档的顶部,然后继续说它将使用 csv-parser 包

 <xsl:use-package name="http://example.com/csv-parser" 
                package-version="*"/>

在 Netbeans (8.2) IDE 中,当我复制给定的示例以将 csv 转换为呈现时,在 (IE 11.1006) 浏览器中生成的输出页面指出:“非静态 Java 函数的第一个参数'parse' 不是有效的对象引用。”

当我查看上面提供的网址时,我只看到一个页面标题,没有包。我是不是该?浏览器从哪里加载包?

我认为错误消息是说包引用不正确。我不了解 W3C (w3.org) 文档吗?他们只是建议界面指南吗?他们不提供实施吗?

为方便起见,这里是上面超链接中提供的代码的副本:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:csv="http://example.com/csv"
   exclude-result-prefixes="xs csv"
   version="3.0">

   <xsl:output indent="yes"/>

   <xsl:use-package name="http://example.com/csv-parser" 
                    package-version="*"/>

   <!-- example input "file"  -->
   <xsl:variable name="input" as="xs:string">
       name,id,postal code
       "Abel Braaksma",34291,1210 KA
       "Anders Berglund",473892,9843 ZD
   </xsl:variable>

   <!-- entry point -->
   <xsl:template name="xsl:initial-template">
       <xsl:copy-of select="csv:parse($input)"/>
   </xsl:template>

</xsl:stylesheet>```

【问题讨论】:

Saxon 9.8 和 9.9 支持 XSLT 3 包,我不知道 NetBeans 是否与任何这些实现​​集成。此外,即使您从命令行运行这些 Saxon 版本,要运行最后一个 sn-p,您也需要在命令行选项 -lib 或配置文件中告诉 Saxon,它可以在其中找到任何与您类似的模块想要使用,不幸的是 XSLT use-package 不允许建议包位置。 【参考方案1】:

如何为 XSLT 处理器提供包位置是特定于处理器的,对于 Saxon 9,您可以从命令行使用 -lib 选项来提供要使用的包的文件名,或者您可以使用具有适当的部分,例如直接从 XSLT 3 测试套件的 GitHub 存储库加载包

<configuration edition="HE" xmlns="http://saxon.sf.net/ns/configuration">
     <xsltPackages>
          <package name="http://example.com/csv-parser" version="1.0"
               sourceLocation="https://github.com/w3c/xslt30-test/raw/master/tests/decl/package/package-100.xsl"
          />
     </xsltPackages>
</configuration>

因此,您基本上需要确保将要使用的包(即您在规范中找到的源代码)安全到本地文件,然后您可以使用 @ 从命令行运行 Saxon 9.8 或更高版本987654324@ 选项,或者您提供带有-config:config.xml 的配置文件。

在https://xqueryfiddle.liberty-development.net/94hwphT,您可以看到它以不同的方式运行,Saxon 9 在 XQuery 代码中运行 XPath 3.1 transform 函数来运行一些 XSLT 的代码,提供内联配置节点也提供内联,直接引用包的源代码来自 W3C 测试套件 GitHub 存储库。

【讨论】:

感谢您抽出宝贵时间做出如此完整的回答。不幸的是,我的用例的重点是为客户提供一个 xslt,他们可以使用它们将加载的 csv 数据文件转换为普通的旧浏览器窗口。看起来 csv-parser 将要求客户(喘气)安装 java 和 saxon jar。当前的解决方案是 (1) 在 csv 文件上运行一批正则表达式替换命令以获取非常通用的 xml 文档。 (2) 然后在通用xml文件之前在浏览器中加载transform。它可以工作,并根据 xslt 转换数据,但它更像是两个步骤,笨重。 如果您想使用 XSLT 3,您需要安装 XSLT 3 处理器。 Saxon 9 也存在于 .NET 版本中,因此它不必是 Java。如果 Java 让您喘不过气来,不知道为什么要使用 NetBeans,那不是 Java IDE 吗? "将要求客户(喘气)安装 java"【参考方案2】:

XSLT 3.0 规范中的 csv-parser 示例的主要目的是作为如何编写包并在应用程序中使用它们的工作示例;它的主要目的不是作为一段工作代码,但如果你愿意,你当然可以这样使用它。

一个版本的 librqry 包包含在 XSLT 3.0 测试套件中

https://github.com/w3c/xslt30-test/blob/master/tests/decl/package/package-100.xsl

主要作者是 Michael Sperberg-McQueen,但 WG 的其他成员也有贡献。在介绍这个包时,规范声明“为了说明的简单,这个例子展示了一个简单、朴素的实现;一个现实的 CSV 解析器会更复杂,并且让这个例子更难理解。” - 这是 Michael Sp-McQ 的典型谦虚。

但代码主要是作为 XSLT 3.0 打包功能的可用性测试编写的,当然它需要 XSLT 3.0 来运行它。

您说“当我查找上面的 url 时”,但这些不是 URL,它们是 URI - 标识符,而不是位置。使用域 example.com 中的 URI,因为它是一个示例。

我不太确定“非静态 Java 函数 'parse' 的第一个参数不是有效的对象引用”错误是什么。意思是,但我强烈怀疑它的出现是因为您没有使用 XSLT 3.0 处理器。在 XSLT 1.0 中,对带前缀的函数名称的函数调用被解释为对外部函数的调用(如果它是 Java 处理器,则通常是 Java 方法),我怀疑这是正在发生的事情。

【讨论】:

感谢 Michael,澄清了 uri/url 的混淆。我可以从 github 获取文件并将其放在与 xslt 相同的目录中,但正如您所指出的 - 似乎 java 处理器正在寻找外部(java?)函数,而不是 xslt 包。后续问题:如何知道在哪里可以找到 uri 引用的实际来源?例如:如果我想把它复制到本地,我怎么知道从哪里得到它?谢谢 其中一些 URI 是命名空间;这些没有任何关联的资源。请参阅jclark.com/xml/xmlns.htm 的说明。对于 XSLT 3.0 包,包的源代码和编译代码可能存在于许多不同的位置(就像 Java 包一样),并且各个 XSLT 处理器将为您提供一种方法来告诉他们在哪里寻找源代码和/或目标代码。

以上是关于如何在转换中使用 xml csv-parser 包? (命名空间给出无效的 obj ref)的主要内容,如果未能解决你的问题,请参考以下文章

XStream(xml/bean转换)

如何在函数中使用getNodeSet(XML包)?

XStream-----把JavaBean转换为xml的工具

转:如何将 Java 项目转换成 Maven 项目

尝试解决在 AndroidManifest.xml 中检测到的重复包

无法访问将 xml 转换为 json