Skip to content

Commit ab99149

Browse files
feat(#213): Add ugly working solution
1 parent f59097a commit ab99149

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (c) 2012-2022, jcabi.com
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met: 1) Redistributions of source code must retain the above
8+
* copyright notice, this list of conditions and the following
9+
* disclaimer. 2) Redistributions in binary form must reproduce the above
10+
* copyright notice, this list of conditions and the following
11+
* disclaimer in the documentation and/or other materials provided
12+
* with the distribution. 3) Neither the name of the jcabi.com nor
13+
* the names of its contributors may be used to endorse or promote
14+
* products derived from this software without specific prior written
15+
* permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19+
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21+
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22+
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28+
* OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
package com.jcabi.xml;
31+
32+
import java.io.StringReader;
33+
import java.util.List;
34+
import java.util.stream.Collectors;
35+
import javax.xml.namespace.NamespaceContext;
36+
import javax.xml.transform.stream.StreamSource;
37+
import net.sf.saxon.s9api.DocumentBuilder;
38+
import net.sf.saxon.s9api.Processor;
39+
import net.sf.saxon.s9api.SaxonApiException;
40+
import net.sf.saxon.s9api.XPathCompiler;
41+
import net.sf.saxon.s9api.XPathExecutable;
42+
import net.sf.saxon.s9api.XPathSelector;
43+
import net.sf.saxon.s9api.XdmItem;
44+
import net.sf.saxon.s9api.XdmNode;
45+
import net.sf.saxon.s9api.XdmValue;
46+
import org.w3c.dom.Node;
47+
48+
public class SaxonDocument implements XML {
49+
50+
private final String text;
51+
52+
/**
53+
* Public constructor from XML as string text.
54+
*
55+
* @param text XML document body.
56+
*/
57+
public SaxonDocument(final String text) {
58+
this.text = text;
59+
}
60+
61+
@Override
62+
public List<String> xpath(final String query) {
63+
Processor processor = new Processor(false);
64+
try {
65+
DocumentBuilder builder = processor.newDocumentBuilder();
66+
XdmNode doc = builder.build(new StreamSource(new StringReader(text)));
67+
XPathCompiler xpathCompiler = processor.newXPathCompiler();
68+
XPathExecutable xpathExec = xpathCompiler.compile(query);
69+
XPathSelector selector = xpathExec.load();
70+
selector.setContextItem(doc);
71+
XdmValue result = selector.evaluate();
72+
return result.stream().map(XdmItem::getStringValue).collect(Collectors.toList());
73+
} catch (SaxonApiException ex) {
74+
throw new RuntimeException(ex);
75+
}
76+
}
77+
78+
@Override
79+
public List<XML> nodes(final String query) {
80+
throw new UnsupportedOperationException();
81+
}
82+
83+
@Override
84+
public XML registerNs(final String prefix, final Object uri) {
85+
throw new UnsupportedOperationException();
86+
}
87+
88+
@Override
89+
public XML merge(final NamespaceContext context) {
90+
throw new UnsupportedOperationException();
91+
}
92+
93+
@Override
94+
public Node node() {
95+
throw new UnsupportedOperationException();
96+
}
97+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.jcabi.xml;
2+
3+
import org.hamcrest.MatcherAssert;
4+
import org.hamcrest.Matchers;
5+
import org.junit.jupiter.api.Test;
6+
7+
class SaxonDocumentTest {
8+
9+
@Test
10+
void findsXpathWithFunctionThatReturnsSeveralItems() {
11+
MatcherAssert.assertThat(
12+
"XMLDocument can handle XPath 2.0 feature - XPath evaluation of concat method, but it can't",
13+
new SaxonDocument(
14+
"<o><o base='a' ver='1'/><o base='b' ver='2'/></o>"
15+
).xpath("//o[@base and @ver]/concat(@base,'|',@ver)"),
16+
Matchers.hasItems("a|1", "b|2")
17+
);
18+
}
19+
}

0 commit comments

Comments
 (0)