Saxon - setParameter作为转换中的节点和访问



我们试图在运行时为转换添加参数。唯一可能的方法是设置每个参数而不是节点。我们还不知道如何为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,有许多选项:

  1. DocumentBuilder.newBuildingStreamWriter()给出了一个扩展XmlStreamWriterBuildingStreamWriter实例,你可以通过使用writeStartElement,writeCharacters,writeEndElement等方法向其写入事件来创建文档;最后在BuildingStreamWriter上调用getDocumentNode(),得到XdmNode。这样做的好处是XmlStreamWriter是一个标准的API,尽管它实际上不是一个很好的API,因为文档不是很好,结果实现在它们的行为上各不相同。

  2. 另一个基于事件的API是Saxon的Push类;这与大多数基于推送的事件api的不同之处在于,它没有一个平坦的方法序列,比如:

builder.startElement('x'); 
builder.characters('abc'); 
builder.endElement();

你有一个嵌套的序列:

Element x = Document.elem('x');
x.text('abc');
x.close(); 
  1. 正如Martin所提到的,有"sapling"API:Saplings.doc().withChild(elem(...).withChild(elem(...))等。这个API与您可能熟悉的任何API都有很大的不同(尽管它受到。net上用于树形结构的LINQ API的影响),但是一旦您习惯了它,它就会读起来非常好。Sapling API在内存中构建了一个非常轻量级的树,并将其转换为一个完全成熟的XDM树,最后调用SaplingDocument.toXdmNode()

  2. 如果您熟悉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);

最新更新