为了账号安全,请及时绑定邮箱和手机立即绑定

如何支持在 ExtensionFunction Saxon HE 9.7 中返回 ArrayList

如何支持在 ExtensionFunction Saxon HE 9.7 中返回 ArrayList

慕田峪7331174 2023-06-04 10:28:12
我有一个使用 Saxon HE 9.7 进行 XML 转换的程序。public String transform() throws TransformerException {    TransformerFactory factory = TransformerFactory.newInstance();    TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) factory;    Configuration saxonConfig = tFactoryImpl.getConfiguration();    Processor processor = (Processor) saxonConfig.getProcessor();    processor.registerExtensionFunction(new Employee());    Source xslt = new StreamSource(new File("mappings.xslt"));    Transformer transformer = factory.newTransformer(xslt);    Source text = new StreamSource(new File("payload.xml"));    transformer.transform(text, new StreamResult(sw));    return sw.toString();}扩展功能类:public class Employee implements ExtensionFunction {private List<HashMap<String, String>> employee = new ArrayList<HashMap<String, String>>();private String employeeName = "John";public List<HashMap<String, String>> getEmployee() {    HashMap<String, String> map1 = new HashMap<>();    map1.put("name", "john");    HashMap<String, String> map2 = new HashMap<>();    map2.put("age", "30");    employee.add(map1);    employee.add(map2);    return employee;}public String getEmployeeName(){    return employeeName;}@Overridepublic XdmValue call(XdmValue[] arg0) throws SaxonApiException {    return new XdmAtomicValue(getEmployeeName());}@Overridepublic SequenceType[] getArgumentTypes() {    return new SequenceType[] {};}@Overridepublic QName getName() {    return new QName("test.extension.Employee", "getEmployeeName");}@Overridepublic SequenceType getResultType() {    return SequenceType.makeSequenceType(ItemType.STRING, OccurrenceIndicator.ONE);}目前,我能够调用从 xslt 返回字符串的 getEmployeeName 方法。但是我如何修改 Employee 类以也支持返回 HasMap 的 ArrayList 即方法 getEmployee() 因为新的 XdmAtomicValue() 方法不将 ArrayList 作为构造函数参数。
查看完整描述

1 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

我将回答 Saxon 9.9,因为这是您真正应该使用的版本。Saxon 9.7 中不存在该类XdmMap,因此使用该版本在 Java 和 XSLT 之间传递映射将变得困难或不可能。


您首先需要确定要返回的 XDM 类型:我假设这可能是map(xs:string, xs:string)*- 这是一系列以字符串为键、以字符串为值的映射。


您首先需要在您的getResultType()方法中将其声明为结果类型。这样做可能就足够了:


public SequenceType getResultType() {

    return SequenceType.makeSequenceType(ItemType.ANY_MAP, OccurrenceIndicator.ZERO_OR_MORE);

}

这并不像它可能的那样精确,但提供更精确的结果类型除了导致 Saxon 对函数实际返回的内容进行更仔细(和昂贵)的检查之外不会实现任何其他目的。如果您想提供更精确的返回类型,则必须使用ItemTypeFactory.newMapType(...).


然后你的call()方法需要返回这个类型的一个实例。


您需要将每个 Employee 表示为XdmMap. 有两种方法可以构造XdmMap.


(a) 您可以构建一个 Java HashMap<String, String>,然后使用静态方法转换它XdmMap.makeMap()


(b) 您可以逐步构建地图:


XdmMap map = new XdmMap();

map = map.put(new XdmAtomicValue("name"), new XdmAtomicValue("John Doe"));

map = map.put(new XdmAtomicValue("age"), new XdmAtomicValue("24"));

等。请注意,它XdmMap是不可变的,因此每个put()操作都会创建一个新XdmMap实例;原来是不变的。


最后,您需要构建这些实例的序列XdmMap。最简单的方法是构造一个List<XdmMap>包含所有地图的 Java,然后将其转换为一个XdmValueusing new XdmValue(Iterable<...> items).


查看完整回答
反对 回复 2023-06-04
  • 1 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信