add ct:parent-element-contains-escaped-question-mark to pending tests

xquery version "3.1";

(:~
 : these tests were created because of
 : https://github.com/eXist-db/exist/issues/1379
~:)

module namespace ct="http://exist-db.org/xquery/test/question-marks-in-contains-function";

declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare namespace xmldb="http://exist-db.org/xquery/xmldb";

declare variable $ct:test :=
    <root>
        <persName xmlns="http://www.tei-c.org/ns/1.0">
            <surname>Hering</surname>, <forename>S(amuel?)</forename>
        </persName>
        <persName xmlns="http://www.tei-c.org/ns/1.0">
            <surname>Hering</surname>, <forename>Samuel</forename>
        </persName>
    </root>;

declare variable $ct:xconf :=
    <collection xmlns="http://exist-db.org/collection-config/1.0">
        <index xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <range>
                <create qname="tei:surname" type="xs:string"/>
                <create qname="tei:forename" type="xs:string"/>
                <create qname="tei:persName" type="xs:string"/>
            </range>
        </index>
    </collection>;

declare
        %test:setUp
function ct:setup() {
    xmldb:create-collection("/db/system/config/db", "test"),
    xmldb:store("/db/system/config/db/test", "collection.xconf", $ct:xconf),
    xmldb:create-collection("/db", "test"),
    xmldb:store("/db/test", "test.xml", $ct:test)
};

declare
        %test:tearDown
function ct:teardown() {
    xmldb:remove("/db/test"),
    xmldb:remove("/db/system/config/db/test")
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(1)
function ct:element-contains-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:forename[fn:contains(., "?")]
    return
        count($hits)
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(0)
function ct:element-contains-escaped-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:forename[fn:contains(., "\?")]
    return
        count($hits)
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(1)
function ct:parent-element-contains-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:persName[fn:contains(., "?")]
    return
        count($hits)
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(0)
function ct:parent-element-contains-escaped-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:persName[fn:contains(., "\?")]
    return
        count($hits)
};

xquery version "3.1";

(:~
 : these tests were created because of
 : https://github.com/eXist-db/exist/issues/1379
~:)

module namespace ct="http://exist-db.org/xquery/test/question-marks-in-contains-function";

declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare namespace xmldb="http://exist-db.org/xquery/xmldb";

declare variable $ct:test :=
    <root>
        <persName xmlns="http://www.tei-c.org/ns/1.0">
            <surname>Hering</surname>, <forename>S(amuel?)</forename>
        </persName>
        <persName xmlns="http://www.tei-c.org/ns/1.0">
            <surname>Hering</surname>, <forename>Samuel</forename>
        </persName>
    </root>;

declare variable $ct:xconf :=
    <collection xmlns="http://exist-db.org/collection-config/1.0">
        <index xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <range>
                <create qname="tei:surname" type="xs:string"/>
                <create qname="tei:forename" type="xs:string"/>
                <create qname="tei:persName" type="xs:string"/>
            </range>
        </index>
    </collection>;

declare
        %test:setUp
function ct:setup() {
    xmldb:create-collection("/db/system/config/db", "test"),
    xmldb:store("/db/system/config/db/test", "collection.xconf", $ct:xconf),
    xmldb:create-collection("/db", "test"),
    xmldb:store("/db/test", "test.xml", $ct:test)
};

declare
        %test:tearDown
function ct:teardown() {
    xmldb:remove("/db/test"),
    xmldb:remove("/db/system/config/db/test")
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(1)
function ct:element-contains-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:forename[fn:contains(., "?")]
    return
        count($hits)
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(0)
function ct:element-contains-escaped-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:forename[fn:contains(., "\?")]
    return
        count($hits)
};

declare
        %test:pending("https://github.com/eXist-db/exist/issues/1379")
        %test:assertEquals(1)
function ct:parent-element-contains-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:persName[fn:contains(., "?")]
    return
        count($hits)
};

declare
        %test:assertEquals(0)
function ct:parent-element-contains-escaped-question-mark() {
    let $hits := doc("/db/test/test.xml")//tei:persName[fn:contains(., "\?")]
    return
        count($hits)
};


[ignore] cleanup script should copy attributes.

svn path=/trunk/eXist/; revision=13188

(:~
    Module to clean up a MODS record. Removes empty elements.
:)
module namespace clean="http:/exist-db.org/xquery/mods/cleanup";

declare namespace mods="http://www.loc.gov/mods/v3";
declare namespace xlink="http://www.w3.org/1999/xlink";

declare function clean:remove-if-empty-text($node as element()) {
    if (empty($node//text())) then
        ()
    else
        element { node-name($node) } {
            $node/@*, for $child in $node/node() return clean:cleanup($child)
        }
};

declare function clean:remove-if-empty-attribute($node as element(), $attr as attribute()?) {
    if (string-length($attr) eq 0 and empty($node//text())) then
        ()
    else
        $node
};

declare function clean:cleanup($node as node()) {
    typeswitch ($node)
        case element(mods:subject) return
            clean:remove-if-empty-text($node)

        case element(mods:place) return
            clean:remove-if-empty-text($node)
        case element(mods:placeTerm) return
            clean:remove-if-empty-text($node)
        case element(mods:dateIssued) return
            clean:remove-if-empty-text($node)
        case element(mods:publisher) return
            clean:remove-if-empty-text($node)
        case element(mods:edition) return
            clean:remove-if-empty-text($node)

        case element(mods:language) return
            clean:remove-if-empty-text($node)

        case element(mods:abstract) return
            clean:remove-if-empty-text($node)

        case element(mods:tableOfContents) return
            clean:remove-if-empty-text($node)

        case element(mods:note) return
            clean:remove-if-empty-text($node)

        case element(mods:identifier) return
            clean:remove-if-empty-text($node)

        case element(mods:location) return
            clean:remove-if-empty-text($node)

        case element(mods:part) return
            clean:remove-if-empty-text($node)

        case element(mods:classification) return
            clean:remove-if-empty-text($node)

        case element(mods:nonSort) return
            clean:remove-if-empty-text($node)
        case element(mods:subTitle) return
            clean:remove-if-empty-text($node)
        case element(mods:partNumber) return
            clean:remove-if-empty-text($node)
        case element(mods:partName) return
            clean:remove-if-empty-text($node)

        case element(mods:relatedItem) return
            clean:remove-if-empty-attribute($node, $node/@xlink:href)

        case element() return
            element { node-name($node) } {
                $node/@*, for $child in $node/node() return clean:cleanup($child)
            }
        default return
            $node
};

declare function clean:clean-namespaces($node as node()) {
    typeswitch ($node)
        case element() return
            if (namespace-uri($node) eq "http://www.loc.gov/mods/v3") then
                element { QName("http://www.loc.gov/mods/v3", local-name($node)) } {
                    $node/@*, for $child in $node/node() return clean:clean-namespaces($child)
                }
            else
                $node
        default return
            $node
};

(:~
    Module to clean up a MODS record. Removes empty elements.
:)
module namespace clean="http:/exist-db.org/xquery/mods/cleanup";

declare namespace mods="http://www.loc.gov/mods/v3";
declare namespace xlink="http://www.w3.org/1999/xlink";

declare function clean:remove-if-empty-text($node as element()) {
    if (empty($node//text())) then
        ()
    else
        element { node-name($node) } {
            $node/@*, for $child in $node/node() return clean:cleanup($child)
        }
};

declare function clean:remove-if-empty-attribute($node as element(), $attr as attribute()?) {
    if (string-length($attr) eq 0 and empty($node//text())) then
        ()
    else
        $node
};

declare function clean:cleanup($node as node()) {
    typeswitch ($node)
        case element(mods:subject) return
            clean:remove-if-empty-text($node)

        case element(mods:place) return
            clean:remove-if-empty-text($node)
        case element(mods:placeTerm) return
            clean:remove-if-empty-text($node)
        case element(mods:dateIssued) return
            clean:remove-if-empty-text($node)
        case element(mods:publisher) return
            clean:remove-if-empty-text($node)
        case element(mods:edition) return
            clean:remove-if-empty-text($node)

        case element(mods:language) return
            clean:remove-if-empty-text($node)

        case element(mods:abstract) return
            clean:remove-if-empty-text($node)

        case element(mods:tableOfContents) return
            clean:remove-if-empty-text($node)

        case element(mods:note) return
            clean:remove-if-empty-text($node)

        case element(mods:identifier) return
            clean:remove-if-empty-text($node)

        case element(mods:location) return
            clean:remove-if-empty-text($node)

        case element(mods:part) return
            clean:remove-if-empty-text($node)

        case element(mods:classification) return
            clean:remove-if-empty-text($node)

        case element(mods:nonSort) return
            clean:remove-if-empty-text($node)
        case element(mods:subTitle) return
            clean:remove-if-empty-text($node)
        case element(mods:partNumber) return
            clean:remove-if-empty-text($node)
        case element(mods:partName) return
            clean:remove-if-empty-text($node)

        case element(mods:relatedItem) return
            clean:remove-if-empty-attribute($node, $node/@xlink:href)

        case element() return
            element { node-name($node) } {
                $node/@*, for $child in $node/node() return clean:cleanup($child)
            }
        default return
            $node
};

declare function clean:clean-namespaces($node as node()) {
    typeswitch ($node)
        case element() return
            if (namespace-uri($node) eq "http://www.loc.gov/mods/v3") then
                element { QName("http://www.loc.gov/mods/v3", local-name($node)) } {
                    for $child in $entry/node() return clean:clean-namespaces($child)
                }
            else
                $node
        default return
            $node
};


[feature] XQuery 3.1 arrow operator

[feature] XQuery 3.1 arrow operator

xquery version "3.0";

module namespace ao="http://exist-db.org/xquery/test/arrowop";

declare namespace test="http://exist-db.org/xquery/xqsuite";

declare
    %test:assertEquals("Hello world")
function ao:func-by-name1() {
    "Hello" => concat(" ", "world")
};

declare
    %test:assertEquals(3)
function ao:func-by-name2() {
    ('A', 'B', 'C') => count()
};

declare
    %test:assertEquals(3)
function ao:func-inline() {
    ('A', 'B', 'C') => (function( $sequence) { count( $sequence)})()
};

declare
    %test:assertEquals(11)
function ao:func-in-sequence1() {
    "Hello" => concat(" world") => string-length()
};

declare
    %test:assertEquals("HELLO", "WORLD")
function ao:func-in-sequence2() {
    "hello world"=>upper-case()=>normalize-unicode()=>tokenize("\s+")
};

declare
    %test:assertEquals("W-E-L-C-O-M-E")
function ao:func-in-sequence3() {
    'w e l c o m e' => upper-case() => tokenize(" ") => string-join('-')
};

declare
    %test:assertEquals("HELLO", "WORLD")
function ao:func-in-sequence-inner() {
    "hello world"=>(function($in) { $in=>upper-case()=>tokenize("\s+") })()
};


improve documentation content

improve documentation content

git-svn-id: 2087087167f935058d19856144d26af79f295c86@106756 62cac252-8da6-4816-9e9d-6dc37b19578c

xquery version "1.0-ml";

(: Copyright 2011-2012 MarkLogic Corporation.  All Rights Reserved. :)

(: An XQuery transform must follow some conventions rigorously:
   *  The transform must be an XQuery library module
   *  The namespace must be http://marklogic.com/rest-api/transform/TRANSFORM_NAME
   *  The namespace prefix must be TRANSFORM_NAME
   *  The library module must have a function with the local name "transform"
      that takes two maps and a document as input and returns a document as output
      The $context map provides environment information including the input type
          and the output type (which may be modified)
      The $params map provides any parameters for the transform
 :)
module namespace html2xhtml = "http://marklogic.com/rest-api/transform/html2xhtml";

import module namespace plugin = "http://marklogic.com/extension/plugin"
    at "/MarkLogic/plugin/plugin.xqy";

declare namespace tidy = "xdmp:tidy";

declare default function namespace "http://www.w3.org/2005/xpath-functions";
declare option xdmp:mapping "false";

(: transform HTML documents into modifiable and indexable XHTML documents :)
declare function html2xhtml:transform(
    $context as map:map,
    $params  as map:map,
    $content as document-node()
) as document-node()
{
    if (empty($content) or exists($content/(element()|binary())))
    then $content
    else
        let $input-type := map:get($context,"input-type")
        return
            if (not($input-type = "text/html"))
            then $content
            else
                let $param-names := map:keys($params)
                let $options     :=
                    if (empty($param-names)) then ()
                    else
                        <options xmlns="xdmp:tidy">{
                            for $param-name in $param-names
                            return element {QName("xdmp:tidy",$param-name)} {
                                text {map:get($params,$param-name)}
                                }
                        }</options>
                let $result      :=
                    if (empty($options))
                    then xdmp:tidy($content)
                    else xdmp:tidy($content, $options)
                let $status      := subsequence($result,1,1)
                return (
                    if (empty($status/tidy:error)) then ()
                    else xdmp:log(
                        "XHTML conversion error for " ||
                        map:get($context,"uri") || ": " ||
                        xdmp:quote($status)
                        ),

                    if (count($result) lt 2) then ()
                    else (
                        map:put($context,"output-type","application/xhtml+xml"),
                        subsequence($result,2,1)
                        )
                    )
};

xquery version "1.0-ml";

(: Copyright 2011-2012 MarkLogic Corporation.  All Rights Reserved. :)

module namespace html2xhtml = "http://marklogic.com/rest-api/transform/html2xhtml";

import module namespace plugin = "http://marklogic.com/extension/plugin"
    at "/MarkLogic/plugin/plugin.xqy";

declare namespace tidy = "xdmp:tidy";

declare default function namespace "http://www.w3.org/2005/xpath-functions";
declare option xdmp:mapping "false";

(: transform HTML documents into modifiable and indexable XHTML documents :)
declare function html2xhtml:transform(
    $context as map:map,
    $params  as map:map,
    $content as document-node()
) as document-node()
{
    if (empty($content) or exists($content/(element()|binary())))
    then $content
    else
        let $input-type := map:get($context,"input-type")
        return
            if (not($input-type = "text/html"))
            then $content
            else
                let $param-names := map:keys($params)
                let $options     :=
                    if (empty($param-names)) then ()
                    else
                        <options xmlns="xdmp:tidy">{
                            for $param-name in $param-names
                            return element {QName("xdmp:tidy",$param-name)} {
                                text {map:get($params,$param-name)}
                                }
                        }</options>
                let $result      :=
                    if (empty($options))
                    then xdmp:tidy($content)
                    else xdmp:tidy($content, $options)
                let $status      := subsequence($result,1,1)
                return (
                    if (empty($status/tidy:error)) then ()
                    else xdmp:log(
                        "XHTML conversion error for " ||
                        map:get($context,"uri") || ": " ||
                        xdmp:quote($status)
                        ),

                    if (count($result) lt 2) then ()
                    else (
                        map:put($context,"output-type","application/xhtml+xml"),
                        subsequence($result,2,1)
                        )
                    )
};