Во-первых, спецификация XBRL для функции, по-видимому, подразумевает, что функция ожидает узел в качестве аргумента и возвращает узел в качестве результата, но в вашей реализации getArgumentTypes () и getResultType () определяют тип как xs: string - такэто нужно изменить.
И функция должна возвращать XdmNode, который является подклассом XdmValue.
Далее, очень неэффективно создавать DocumentBuilderFactory и XPathFactory, создавая дерево документов XMLи компилирование выражения XPath каждый раз, когда выполняется ваша функция. Я сильно подозреваю, что ничего из этого не требуется.
Вместо того, чтобы this.getXbrl () возвращал необработанный лексический документ как byte [], пусть он возвращает предварительно скомпонованный XdmNode, представляющий дерево документа. И тогда я хотел бы предложить, чтобы вместо выбора в этом дереве с помощью XPath вы использовали саксонский API-интерфейс навигации, похожий на linq. Если этот XdmNode находится в переменной «root», то выражение XPath
//xbrli:xbrl/xbrli:context[@id=("+arg+"/@contextRef"+")
преобразуется в нечто вроде
root.select(descendant("xbrl").then(child("context)).where(attributeEq("id", arg))
(за исключением того, что я не совсем уверен, что вы передаетеas arg, чтобы ваше XPath-выражение имело смысл).
Но вы можете использовать XPath, если хотите;просто используйте интерфейсы Saxon s9api для XPath и убедитесь, что выражение XPath скомпилировано только один раз и используется повторно. Тогда просто получить XdmNode как результат вашего выражения XPath, который может быть возвращен непосредственно как результат вашей функции расширения.