Skip to content

Commit

Permalink
feat(#213): Add ugly working solution
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Jul 19, 2023
1 parent f59097a commit ab99149
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
97 changes: 97 additions & 0 deletions src/main/java/com/jcabi/xml/SaxonDocument.java
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2012-2022, jcabi.com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met: 1) Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. 3) Neither the name of the jcabi.com nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jcabi.xml;

import java.io.StringReader;
import java.util.List;
import java.util.stream.Collectors;
import javax.xml.namespace.NamespaceContext;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathExecutable;
import net.sf.saxon.s9api.XPathSelector;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmValue;
import org.w3c.dom.Node;

public class SaxonDocument implements XML {

private final String text;

/**
* Public constructor from XML as string text.
*
* @param text XML document body.
*/
public SaxonDocument(final String text) {
this.text = text;
}

@Override
public List<String> xpath(final String query) {
Processor processor = new Processor(false);
try {
DocumentBuilder builder = processor.newDocumentBuilder();
XdmNode doc = builder.build(new StreamSource(new StringReader(text)));
XPathCompiler xpathCompiler = processor.newXPathCompiler();
XPathExecutable xpathExec = xpathCompiler.compile(query);
XPathSelector selector = xpathExec.load();
selector.setContextItem(doc);
XdmValue result = selector.evaluate();
return result.stream().map(XdmItem::getStringValue).collect(Collectors.toList());
} catch (SaxonApiException ex) {
throw new RuntimeException(ex);
}
}

@Override
public List<XML> nodes(final String query) {
throw new UnsupportedOperationException();
}

@Override
public XML registerNs(final String prefix, final Object uri) {
throw new UnsupportedOperationException();
}

@Override
public XML merge(final NamespaceContext context) {
throw new UnsupportedOperationException();
}

@Override
public Node node() {
throw new UnsupportedOperationException();
}
}
19 changes: 19 additions & 0 deletions src/test/java/com/jcabi/xml/SaxonDocumentTest.java
@@ -0,0 +1,19 @@
package com.jcabi.xml;

import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;

class SaxonDocumentTest {

@Test
void findsXpathWithFunctionThatReturnsSeveralItems() {
MatcherAssert.assertThat(
"XMLDocument can handle XPath 2.0 feature - XPath evaluation of concat method, but it can't",
new SaxonDocument(
"<o><o base='a' ver='1'/><o base='b' ver='2'/></o>"
).xpath("//o[@base and @ver]/concat(@base,'|',@ver)"),
Matchers.hasItems("a|1", "b|2")
);
}
}

0 comments on commit ab99149

Please sign in to comment.