我想通过使用命令行执行来执行XSLT 2.0转换.我听说我可以通过shell命令使用Saxon库java -jar sax.jar -input foo.xml -xsl foo.xsl -output bar.xml.有谁知道我到底能达到那个目标?
顺便说一句,我不仅限于Java.任何其他shell解决方案都可以.
我在Mac OS X和Saxon-HE 9.3.0.5上使用Java SE 6.ServiceLoader无法找到Saxon的实现javax.xml.xpath.XPathFactory.
mac:test2 ludo$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
Run Code Online (Sandbox Code Playgroud)
查找过程的第3点中newInstance的javax.xml.xpath.XPathFactory状态方法的javadoc,用于本地化实现:
要求类加载器提供与资源目录META-INF/services中的javax.xml.xpath.XPathFactory匹配的服务提供者提供者配置文件.有关文件格式和解析规则,请参阅JAR文件规范.
JAR文件规范的服务提供者部分声明:
该文件应包含以换行符分隔的唯一具体提供程序类名称列表.
但是,如果我提取saxon9he.jar文件并查看META-INF目录,我会看到:
mac:Java ludo$ mkdir test
mac:Java ludo$ cd test
mac:test ludo$ jar fx ../saxon9he.jar
mac:test ludo$ cat META-INF/services/javax.xml.xpath.XPathFactory
net.sf.saxon.xpath.XPathFactoryImpl
http\://java.sun.com/jaxp/xpath/dom: net.sf.saxon.xpath.XPathFactoryImpl
http\://saxon.sf.net/jaxp/xpath/om: net.sf.saxon.xpath.XPathFactoryImpl
Run Code Online (Sandbox Code Playgroud)
第一行是正确的,但我不明白为什么有两个额外的行,看起来这些行导致ServiceLoader的麻烦.我看到了一个测试示例的问题,我写了解了用于查找提供程序的机制.我们可以看到saxon9he.jar在CLASSPATH中.
mac:services ludo$ java ServicesTest
CLASSPATH = ..., /Users/ludo/Library/Java/saxon9he.jar, ...
Service XPathFactory: java.util.ServiceLoader[javax.xml.xpath.XPathFactory]
ServiceConfigurationError: javax.xml.xpath.XPathFactory: jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal …Run Code Online (Sandbox Code Playgroud) 我正在尝试从ant文件运行XSLT转换.
我正在使用带有saxon 9解析器的XSLT 2.0样式表(支持XSLT 2.0).
问题是,似乎ant始终调用XSLT 1.0解析器.
这是我的蚂蚁文件:
<xslt style="stylesheet.xslt"
basedir="core/"
extension=".xml"
destdir="core/"
classpath="D:\\DevTools\\saxon\\bin\\saxon9.jar">
</xslt>
Run Code Online (Sandbox Code Playgroud)
如果我直接调用它(没有蚂蚁),它就可以了.
任何的想法 ?
在Java中,从TransformerFactory用于创建对象到处理XSLT,它具有以下方法:
newTransformer它创建了 Transformer对象,可以将XML转换为结果.newTemplates它创建了Templates可以创建的对象Transformer.Transformer明确说明的文档:
变压器可以多次使用.
我的应用程序使用相同的XSLT处理各种不同的XML.在程序开始时,我用newTransformer它创建一个Transformer然后重新使用它来处理所有XML(确保它是同步的,所以我只在一个线程中使用它;并reset()在每次处理之前调用它的方法.).
这样我就不会为每个XML I进程重新编译XSLT.
那么这个newTemplates和Templates对象的重点是什么?我应该使用它,并Transformer为每个XML 创建一个新对象吗?
每当我有一个XSLT import语句时,Saxon处理器就会出错.这是错误:
XTSE0165: I/O error reported by XML parser processing file: shared/test.xslt (The system cannot find the path specified):
Run Code Online (Sandbox Code Playgroud)
以下是我的XSLT文档的样子:
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version='2.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:fn='http://www.w3.org/2005/02/xpath-functions'
xmlns:xs='http://www.w3.org/2001/XMLSchema'
>
<xsl:import href="shared/test.xslt"/>
...
Run Code Online (Sandbox Code Playgroud)
我的java代码
TransformerFactory transformerFactory = TransformerFactoryImpl.newInstance();
transformerFactory.setURIResolver(uriResolver); //my own custom URI resolver
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltInputStream)); //this is where the error occurs when I debug!
Run Code Online (Sandbox Code Playgroud)
永远不会触发URI解析器类!它扼杀了上面的newTransformer()方法....我尝试过XsltCompiler等同样的事情......如果我删除了import语句,一切正常!它找不到要导入的文件,但这就是为什么我有解析器类来帮助它找到文件,但它永远不会触发解析器并且无法定位要导入的文件!
我该如何解决这个问题?
我目前正在使用各种版本的Saxon-Processor进行纯XSL转换.下面是我的简短样式表,简化了我的问题的需求:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:foo="bar">
<xsl:output encoding="UTF-8" method="text"/>
<xsl:template match="/">
<xsl:text>Call of func_1: </xsl:text>
<xsl:value-of select="foo:func_1()"/>
<xsl:text>
Call of func_1: </xsl:text>
<xsl:value-of select="foo:func_1()"/>
<xsl:text>
Call of func_1: </xsl:text>
<xsl:value-of select="foo:func_1()"/>
<xsl:text>
Call of func_2: </xsl:text>
<xsl:value-of select="foo:func_2()"/>
</xsl:template>
<xsl:function name="foo:func_1" as="xs:string">
<!-- do some other stuff -->
<xsl:value-of select="foo:func_2()"/>
</xsl:function>
<xsl:function name="foo:func_2" as="xs:string">
<xsl:variable name="node">
<xsl:comment/>
</xsl:variable>
<xsl:sequence select="generate-id($node)"/>
</xsl:function>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
描述
foo:func_1是一个包装函数,用于返回第二个函数的值+执行其他操作,可以忽略.这个函数调用的概念是强制性的!
foo:func_2为元素生成唯一的id.此元素在名为"node"的本地范围变量中创建.
基于Saxon版本的不同结果
预期结果:
Call of func_1: d2
Call of func_1: d3
Call of func_1: …Run Code Online (Sandbox Code Playgroud) 我可以轻松地在命令行中运行以下命令来转换 xml 文件:
java -jar saxon9he.jar -o:outputfile.xml data.xml transform.xslt
Run Code Online (Sandbox Code Playgroud)
我想从一个 java 文件中得到完全相同的结果,这样我就可以在我正在制作的程序的一部分中使用它。我已将 saxon9he.jar 放在构建路径中,但如何在命令行之外调用相同的命令?
我有以下代码:
// xpath evaluates to net.sf.saxon.xpath.XPathEvaluator
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xpath.compile("/foo/bar");
Object evaluate = expression.evaluate(someXML, XPathConstants.NODE);
Object evaluate2 = expression.evaluate(someXML, XPathConstants.NODESET);
System.out.println(evaluate!=null?evaluate.getClass():"null");
System.out.println(evaluate2!=null?evaluate2.getClass():"null2");
System.out.println(evaluate instanceof Node);
System.out.println(evaluate2 instanceof NodeList);
Run Code Online (Sandbox Code Playgroud)
这就是结果......
class net.sf.saxon.tinytree.TinyElementImpl class java.util.ArrayList false false
只是为了澄清,如果我这样做:
org.w3c.dom.Node node = (org.w3c.dom.Node)evaluate;
Run Code Online (Sandbox Code Playgroud)
要么
org.w3c.dom.NodeList node = (org.w3c.dom.NodeList)evaluate2;
Run Code Online (Sandbox Code Playgroud)
我得到了 ClassCastException
怎么可能?根据Suns Java 1.5 API NODE和NODESET应分别映射到org.w3c.dom.Node和org.w3c.dom.NodeList
只是澄清2是的我知道Node是一个iterface,getClass()返回一个具体的类.
使用.NET版本的Saxon 9.4,我运行一个命令行,如:
Query.exe -s:myfile.xml -qs:/cruisecontrol/build/msbuild[@success='true']/project[1]/target[@name='GetLatestSource']/message[last()]/text()
Run Code Online (Sandbox Code Playgroud)
我得到了一个结果
<?xml version="1.0" encoding="UTF-8"?>375
Run Code Online (Sandbox Code Playgroud)
如何关闭XML标头(省略XML声明)以便我得到375输出?我已经检查了文档,但也许我只是错过了它.
我在我的应用程序中使用Xalan,但需要使用Saxon和参考实现来生成测试输出以进行比较.我想在单元测试中使用它们.但是,一旦我在项目.pom中添加对Saxon的依赖,应用程序似乎在测试期间对所有xslt和XPath操作使用Saxon:
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.4</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这使得主应用程序在生成输出时由于不同的XPath行为而失败.在测试范围之外运行主应用程序时,它可以工作.
如何使用Xalan运行主应用程序,但在测试期间使用Saxon进行测试?
我在运行Xalan和Saxon部件之前尝试设置以下属性:
System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl ");
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
Run Code Online (Sandbox Code Playgroud)
我也尝试将Xalan和Saxon部件放在不同的项目中,我也尝试在第三个项目中使用它们,结果相同.