首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在撒克逊中使用外部变量

在撒克逊中使用外部变量
EN

Stack Overflow用户
提问于 2019-02-19 13:54:29
回答 1查看 686关注 0票数 2

我有一个将Json转换为Json的XQuery。我制作了一个在命令行上工作的演示版本,我想在java中使用它。

问题是我不知道如何在XQuery中设置参数。

我的源文件"1.json":

代码语言:javascript
运行
复制
{
 "FirstName": "Fred",
 "Surname": "Smith",
 "Age": 28,
 "Phone": [{
   "type": "home",
   "number": "0203 544 1234"
  }, {
   "type": "office",
   "number": "01962 001234"
  }, {
   "type": "office",
   "number": "01962 001235"
  }, {
   "type": "mobile",
   "number": "077 7700 1234"
  }
 ]
}

我想使用“XQuery”的XQuery.xq:

代码语言:javascript
运行
复制
xquery version "3.1";
declare namespace array = "http://www.w3.org/2005/xpath-functions/array";
declare namespace map = "http://www.w3.org/2005/xpath-functions/map";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";

let $j := json-doc( 'src/test/resources/1.json' )
where ("Fred" = $j?FirstName or 30 != $j?Age) (:predicate on the highest level:)
return array {
  for $i in (1 to $j?Phone => array:size()) (:predicate on the next level:)
  let $e := $j?Phone($i)
  where ($e?type = "home" or fn:matches($e?type, "^mob.*$")) (:implementing like using regular expressions % => .*, ? => . , ^/$ Start/End of line  :)
  return map {
    "Name (First)": data($j?FirstName),
    "Name (Last)": data($j?Surname),
    "age": data($j?Age),
    "Phone": data($e?number),
    "ConstantValue": "TEST"
  }
}

命令行:

代码语言:javascript
运行
复制
java -cp saxon9he.jar net.sf.saxon.Query -t -q:test\Query.xq >test\Test.json

在Java中,我编写了以下内容(不工作!=>我得到一个SXXP0003: SXXP0003解析器报告的错误:prolog中不允许内容):

代码语言:javascript
运行
复制
    @Test
public void test_XQuery() throws Exception {
    runXQuery("/1.json", "/XQuery.xq", "/1_Output.json");
}

private void runXQuery(String datafile, String xQueryFile, String expectedOutput) throws Exception {
    InputStream dataStream = getClass().getResourceAsStream(datafile);
    InputStream xQueryStream = getClass().getResourceAsStream(xQueryFile);

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    run(dataStream, xQueryStream, outputStream);
    String json = outputStream.toString();

    String expected = StreamUtils.copyToString(getClass().getResourceAsStream(expectedOutput), Charset.defaultCharset());
    assertEquals(expected, json);
}

private static void run(InputStream input, InputStream query, OutputStream output) throws SaxonApiException {
    Configuration config = Configuration.newConfiguration();
    Processor processor = new Processor(config);
    XQueryCompiler compiler = processor.newXQueryCompiler();
    XQueryExecutable executor = compiler.compile(query);
    XQueryEvaluator evaluator = executor.load();

    Source sourceInput = new SAXSource(new InputSource(input));
    DocumentBuilder builder = processor.newDocumentBuilder();
    XdmNode doc = builder.build(sourceInput);
    evaluator.setContextItem(doc);

//    QName qName = new QName("input");
//    evaluator.setExternalVariable(qName, doc);

    Serializer out = processor.newSerializer(output);
    out.setOutputProperty(Serializer.Property.METHOD, "json");

    evaluator.run(out);
}

我的问题是:我应该如何更改我的"XQuery.xq“和我的Java代码,以便我可以使用多个输入文件。例如"2.json",..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-19 15:56:55

首先,这个查询中没有任何外部变量,这使得问题标题相当混乱。将像这样声明一个外部变量:

代码语言:javascript
运行
复制
declare variable $param as xs:string external;

您所得到的错误是因为您提供了一个JSON文件作为SAXSource的输入。SAX用于读取XML文件,而来自XML解析器(SXXP0003)的错误是因为XML解析器无法读取JSON文件。

如果您想用要读取的JSON文件的文件名参数化查询,我会这样做:

代码语言:javascript
运行
复制
declare variable $jsonFile as xs:string external;
let $j := json-doc($jsonFile)...

然后使用以下方法提供文件名

代码语言:javascript
运行
复制
QName qName = new QName("jsonFile");
evaluator.setExternalVariable(qName, "src/test/resources/1.json");

剩下的唯一问题是有关相对文件名的解析。我在这里所做的,就是文件名“src/test/resources.”将被解释为相对于查询的位置(静态基URI),在您的情况下,这个位置是未知的,因为您将查询作为匿名InputStream提供。您可以使用XQueryCompiler.setBaseURI()为查询设置一个基URI,也可以在您的Java代码中解析文件名,并为JSON输入提供一个绝对URI。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54767940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档