0

I would like to normalize XSD input file to put xs: before any XSD elements without xs: prepended with XQuery.

copy $c:=doc("test.xsd")
modify
(
  if($c/schema)
  then
  (
    for $item in $c//*
    where substring($item/text(), 1, 3) != "xs:"
    return rename node $item as concat("xs:", $item/text())
  )
  else ()
)
return $c

Running this xqy on an input XSD without xs: prepended returns input file unchanged. I do update the $c and return it. So what is wrong?

input file:

<?xml version="1.0"?>
<schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<element name="note" type="xs:string"/>

</schema>

expected output:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="note" type="xs:string"/>

</xs:schema>

PS: It seems that my question causes confusion. I need xs: present because I have another text processing program which only handles elements with xs: prefix.

JACK M
  • 2,627
  • 3
  • 25
  • 43
  • The things you're trying to update aren't text nodes at all, and xs: isn't a textual prefix, it's a namespace alias. So trying to match substrings of `text()` nodes makes no sense at all. – Charles Duffy Jan 15 '17 at 16:29
  • that is to say, what you're *really* trying to do, from an XML-document-semantics perspective (which is the level at which any BaseX query is working) is replacing elements in the default namespace with like-named elements in the `http://www.w3.org/2001/XMLSchema` namespace. – Charles Duffy Jan 15 '17 at 16:30
  • ...there are actually some answers floating around on how to do that in XSLT -- see ie. http://stackoverflow.com/questions/9026224/how-to-mimic-copy-namespaces-no-in-xslt-1-0/9030832#9030832 -- but I can't help you in XQUF. – Charles Duffy Jan 15 '17 at 16:33
  • (though those approaches might provide useful hints -- looking at the XQUF standard, copy-namespaces can be turned off there too). – Charles Duffy Jan 15 '17 at 16:35
  • BTW, if your document just set the *default* namespace to `http://www.w3.org/2001/XMLSchema`, then you wouldn't need `xs:` prefixes on everything. – Charles Duffy Jan 15 '17 at 16:38
  • (When you say "another text-processing tool", do you mean a *text*-processing tool, or an *XML*-processing tool? Because if it's a tool that complies with the XML standard, it only cares about whether the namespace is `http://www.w3.org/2001/XMLSchema`, not whether it got there via a `xmlns:ns="http://www.w3.org/2001/XMLSchema"` and a paired `xs:` prefix on the element, or by a completely different prefix name pointing to the same namespace, or by a default namespace set, as with `xmlns="http://www.w3.org/2001/XMLSchema"`; and if it doesn't comply, maybe you shouldn't use it for XML). – Charles Duffy Jan 17 '17 at 15:42
  • @CharlesDuffy Sorry for the late response. I am in vacation. The text processing program doesn't recognize XML syntax. – JACK M Jan 29 '17 at 03:35

1 Answers1

1

This should work (it’s pretty similar to your approach):

copy $doc := doc("test.xsd")
modify (
  if($doc/*:schema) then (
    for $item in $doc//*
    let $name := name($item)
    where not(starts-with($name, 'xs:'))
    let $new-name := xs:QName('xs:' || replace($name, '^.+:', ''))
    return rename node $item as $new-name
  )
  else ()
)
return $doc
Christian Grün
  • 6,012
  • 18
  • 34