Christian, I love the contains token! Didn't know about that.

The reason I'm looking for a switch instead of the if then else is more for readability, there are a lot of elements and classes in DITA, when you're indenting to character 2xx it starts to get hard to manage! Maybe I'll bug people on the xquery side with this case. DITA is popular enough that it should matter.

Mark, good point, values for @ class in DITA start and end with spaces, and you always match on space-value-space. I omitted the spaces to focus on my current issue, but it looks like you have a bionic eye for finding potential issues :-P.

Thank you for your feedback on this!



On Fri, Mar 13, 2015 at 4:52 AM, Christian Grün <christian.gruen@gmail.com> wrote:
A little addition: XQuery 3.1 provides the function contains-token to
request single values of attributes. It basically does what Marc
proposed [1]:

  let $input := <a class='ancestor field'/>
  let $class := $input/@class
  return if(contains-token($class, 'ancestor')) then (
    1
  ) else if(contains-token($class, 'descendant')) then (
    2
  ) else (
    0
  )

This is one more way to do it:

  let $input := <a class='ancestor field'/>
  let $tokens := map:merge(
    tokenize($input/@class, '\s+') ! map { .: true() }
  )
  return if($tokens?ancestor) then (
    1
  ) else if($tokens?descendant) then (
    2
  ) else (
    0
  )

Best,
Christian

[1] http://docs.basex.org/wiki/XQuery_3.1#fn:contains-token



On Thu, Mar 12, 2015 at 10:45 PM, Marc van Grootel
<marc.van.grootel@gmail.com> wrote:
>
> Hi France,
>
> Typeswitch is not the right tool for this.
>
> From the spec:
>
> [74]   TypeswitchExpr   ::=   "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? "return" ExprSingle
> [75]   CaseClause   ::=   "case" ("$" VarName "as")? SequenceTypeUnion "return" ExprSingle
> [76]   SequenceTypeUnion   ::=   SequenceType ("|" SequenceType)*
>
>
> As the name implies it is meant for checking (sequence) types and not for arbitrary XPath expressions.
>
> Also, using contains isn't watertight as contains('foobar','foo') would match as well. I would probably use a function like this
>
> declare function in-class($node as element(), $class as xs:string) as xs:boolean {
>   $class = tokenize($node/@class,'\s+')
> }
>
> Do check performance in your situation. In case you need to do many checks on the same class attribute you may want to bind the tokenized value list with a let instead of using this function.
>
> I also remember that Michael Kay is looking into improving on exactly this use case. But that doesn't help you now.
>
> Cheers,
> --Marc
>
> On 12 mrt. 2015, at 20:33, France Baril <france.baril@architextus.com> wrote:
>
> Hi,
>
> I'm working on a new DITA project. The DITA standard is used for technical documentation. It creates XML models with inheritance by using @class="ancestor parent child". If the child should behave like it's ancestor the XSL would say:
>    <template match="contains(@class, 'ancestor')"> ... </template>
>
> The advantage is that the model can evolve and when new elements are added, you only need to code transformations for the differences.
>
> I am trying to figure out if I can use type switching with contains in attribute. Search gets me no syntax for something like this:
>
>  typeswitch ($node)
>     case attribute(contains(class, 'ancestor'))
>
> Maybe I should register to the xquery group to get an answer, but since I'm already here, I though I should ask, and maybe there is a BaseX specific option. I mean other that an unmanageable number of 'if then else' statements.
>
> Thanks!
>
>
>
> --
> France Baril
> Architecte documentaire / Documentation architect
> france.baril@architextus.com



--
France Baril
Architecte documentaire / Documentation architect
france.baril@architextus.com