我们试图在运行时为转换添加参数。唯一可能的方法是设置每个参数而不是节点。我们还不知道如何为setParameter创建一个节点。
当前setParameter:
QName TEST XdmAtomicValue 24
预期setParameter:
<TempNode> <local>Value1</local> </TempNode>
我们搜索并尝试创建一个XdmNode和XdmItem。
如果您想通过解析XML来创建XdmNode
,最好的方法是:
DocumentBuilder db = processor.newDocumentBuilder();
XdmNode node = db.build(new StreamSource(
new StringReader("<doc><elem/></doc>")));
还可以传递包含词法XML的字符串作为参数值,然后通过调用XPathparse-xml()
函数将其转换为树。
如果您想以编程方式构造XdmNode,有许多选项:
DocumentBuilder.newBuildingStreamWriter()
给出了一个扩展XmlStreamWriter
的BuildingStreamWriter
实例,你可以通过使用writeStartElement
,writeCharacters
,writeEndElement
等方法向其写入事件来创建文档;最后在BuildingStreamWriter
上调用getDocumentNode()
,得到XdmNode
。这样做的好处是XmlStreamWriter
是一个标准的API,尽管它实际上不是一个很好的API,因为文档不是很好,结果实现在它们的行为上各不相同。另一个基于事件的API是Saxon的Push类;这与大多数基于推送的事件api的不同之处在于,它没有一个平坦的方法序列,比如:
builder.startElement('x');
builder.characters('abc');
builder.endElement();
你有一个嵌套的序列:
Element x = Document.elem('x');
x.text('abc');
x.close();
正如Martin所提到的,有"sapling"API:
Saplings.doc().withChild(elem(...).withChild(elem(...))
等。这个API与您可能熟悉的任何API都有很大的不同(尽管它受到。net上用于树形结构的LINQ API的影响),但是一旦您习惯了它,它就会读起来非常好。Sapling API在内存中构建了一个非常轻量级的树,并将其转换为一个完全成熟的XDM树,最后调用SaplingDocument.toXdmNode()
。如果您熟悉DOM、JDOM2或XOM,则可以使用这些库中的任何一个构建树,然后将其转换为Saxon使用。这有点复杂,只适合那些已经大量使用第三方树模型的应用程序(或者喜欢这些api并且喜欢它们的用户)。
在Saxon Java s9api中,您可以将临时树构造为SaplingNode/SaplingElement/SaplingDocument,参见https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/sapling/SaplingDocument.html和https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/sapling/SaplingElement.html。
为您提供一个从Map构造的简单示例,您似乎想这样做:
Processor processor = new Processor();
Map<String, String> xsltParameters = new HashMap<>();
xsltParameters.put("foo", "value 1");
xsltParameters.put("bar", "value 2");
SaplingElement saplingElement = new SaplingElement("Test");
for (Map.Entry<String, String> param : xsltParameters.entrySet())
{
saplingElement = saplingElement.withChild(new SaplingElement(param.getKey()).withText(param.getValue()));
}
XdmNode paramNode = saplingElement.toXdmNode(processor);
System.out.println(paramNode);
输出例如<Test><bar>value 2</bar><foo>value 1</foo></Test>
。
所以关键是要理解withChild()
返回一个新的SaplingElement
。
代码可以使用流进行压缩,例如
XdmNode paramNode2 = Saplings.elem("root").withChild(
xsltParameters
.entrySet()
.stream()
.map(p -> Saplings.elem(p.getKey()).withText(p.getValue()))
.collect(Collectors.toList())
.toArray(SaplingElement[]::new))
.toXdmNode(processor);
System.out.println(paramNode2);