I am attempting to insert new elements into an xml document using BaseX.
declare variable $part external;
insert nodes $part as first into db:open("PARTDB")/assembly[#name="ZB09010"]
I am using the BaseX GUI for my testing and have defined the $part variable (by clicking on the $ icon).
If I use a "local" variable using for example
let $up := <Employee Name="Joe">
<Personal>
<SSN>666-66-1234</SSN>
</Personal>
<StaffInfo>
<Position>Doctor</Position>
<AccountableTo>Jeff</AccountableTo>
</StaffInfo>
</Employee>
return
insert node $up as last into doc('office')/Staff
then the insert works correctly, however, with the external variable each character that is a reserved xml character is converted to the xml escape character sequence e.g.
example: < becomes <
I have succeeded in making it work by wrapping the variable with a function xquery:eval($part) but this feels to me like a hack.
Is there a type other than xs:string I should use to prevent the translation?
Or is there some function I need to use with the external variable to prevent the translation.
I also tried to wrap the $part xml content with CDATA but the xml was still converted to escape characters.
It looks to me as if the value you are supplying for $part is not a node, but a string containing lexical XML. Converting lexical XML to a node tree is called parsing, so you need to parse the string to create a node (tree). You could do this by calling the fn:parse-xml function.
Related
xquery version "1.0-ml";
declare function local:sortit(){
for $i in ('a','e','f','b','d','c')
order by $i
return
element Result{
element N{1},
element File{$i}
}
};
local:sortit()
the above code is sample, I need the data in this format. This sorting function is used multiple places, and I need only element N data some places and only File element data at other places.
But the moment I use the local:sortit()//File. It removes the sorting order and gives the random output. Please let me know what is the best way to do this or how to handle it.
All these data in File element is calculated and comes from multiple files, after doing all the joins and calculation, it will be formed as XML with many elements in it. So sorting using index and all is not possible here. Only order by clause can be used.
XPath expressions are always returned in document order.
You lose the sorting when you apply an XPath to the sequence returned from that function call.
If you want to select only the File in sorted order, try using the simple mapping operator !, and then plucking the F element from the item as you are mapping each item in the sequence:
local:sortit() ! File
Or, if you like typing, you can use a FLWOR to iterate over the sequence and return the File:
for $result in local:sortit()
return $result/File
My XQuery script:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "text";
for $row in all/row
return ('"<row>","',data($row),'"
')
My XML:
<all>
<row>one</row>
<row>two</row>
<row>three</row>
</all>
My command line:
java -cp …/saxon9he.jar net.sf.saxon.Query '!omit-xml-declaration=yes' -s:./trouble-with-output-escaping.xml -q:./trouble-with-output-escaping.xqy
My output as created by saxon9he:
"<row>"," one "
"<row>"," two "
"<row>"," three "
I actually want to have output like this:
"<row>","one"
"<row>","two"
"<row>","three"
During my web investigation I came across XSLT's disable-output-escaping.
I thought: if XQuery had that, that might help.
Update/0:
Actually nothing (visible) was wrong with the above XQuery script.
The namespace declaration above needs to get replaced by this one:
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
Looks the same, but it isn't, as Michael pointed out.
Having completed this, the above is an example of how to create text output using XQuery.
In some other place Michael showed, how get rid of the space (0x20), that is being used to separate the lines, i.e. the space character preceding lines 2 to the end:
string-join(…,"")
where "…" would be the entire FLWOR.
It's doing the right thing if you set output method "text" from the command line, that is
java net.sf.saxon.Query -q:test.xquery -s:test.xml -t !method=text
but you had me baffled as to why setting the serialization options from within the query isn't working. Looking at it in the debugger, though, I see that your URI, which looks like
http://www.w3.org/2010/xslt-xquery-serialization
actually contains several occurrences of decimal 8203, hex 200B, which is a zero-width space. This means the URI doesn't match the serialization output URI, and "declare option" with an unrecognized URI is ignored.
I have been using and still learning query expr(). I have a complex query where I cannot use if first to check if a parameter is '' - empty string.
I have to check it inside andX with nested orX using something like:
->andWhere($expr->orX($expr->eq(':sid', ''), $expr->neq('s.id', ':sid')))
Note: I know this line can be done by using if check first, I am using it just for an example, I got error says:
Error: Expected Literal, got ' OR '
I really need to compare empty string inside expr(), how?
Because '' is not an empty string. It's nothing and so it evaluates to nothing in DQL/SQL. Normally doctrine expects an named parameter. Either you create one to get quoted empty string or supply an empty string quoted by yourself.
Named parameter:
$qb->expr->eq('foo', ':foo');
$qb->expr->setParameter('foo', '');
quoted by yourself:
$qb->expr->eq('foo', "''");
I have a table named CASE.
And let's say I have the ff code:
declare
a CASE%rowtype;
begin
null;
end;
The above code will throw the error: PLS-00103: Encountered the symbol "CASE" when expecting one of the following: ...
Is there anyway for me to create a variable of CASE%rowtype without manually creating the datatype itself? Thanks!
as Case is a reserved keyword,
you can escape it with double quotes
a "CASE"%rowtype;
useless to say that you should avoid reserved keywords in object naming... (or not that useless ?)
I am trying this in an XQuery (assume that doc('input:instance') does indeed return a valid XML document) which is generated using XSLT
let $a:= <xsl:text>"<xsl:copy-of select="doc('input:instance')//A" />"</xsl:text>
let $p := <xsl:text>"<xsl:copy-of select="doc('input:instance')//P" />"</xsl:text>
let $r := <xsl:text>"<xsl:copy-of select="doc('input:instance')//R" />"</xsl:text>
But I get the error:
xsl:text must not contain child elements
How do I retrieve XML results using the XPath in xsl:copy-of and then encode the special characters received in the result while formatting the result as string? I would be happy to use CDATA section if that's possible (if I do that instead of xsl:text above, xsl:copy-of is not evaluated since it becomes part of CDATA section).
Obviously I am a newcomer to XSL...
What you need here is the ability to serialize an XML document (here the document returned by doc()) using the XML serialization, into a string.
Various XQuery implementation have extension functions for this purpose. For example, if you are using Saxon:
saxon:serialize(document, 'xml')
This has nothing to do with XQuery (you could be building the XSLT stylesheet with any language, even XSLT itslef!).
From http://www.w3.org/TR/xslt20/#xsl-text
<!-- Category: instruction -->
<xsl:text
[disable-output-escaping]? = "yes" | "no">
<!-- Content: #PCDATA -->
</xsl:text>
[...] The content of the xsl:text
element is a single text node whose
value forms the string value of the
new text node.