Data selection from XML files.
Using this module enables data to be accessed which is defined in XML files.
The functions of the xmlquery module support the xmlquery query language of the same name for easy editing of XML files. Before executing an xmlquery statement, all tags of the current statement environment and all Function Variables are replaced with their current values.
Important note: xmlquery requires a fully defined XML structure to evaluate where conditions. Missing elements and attributes can be defined with dummy definitions in the xentities.
The xmlquery language has the keywords:
With the help of xmlquery you can test xmlquery statements.
The names of the elements and attributes of the XML file are used as identifiers for the data columns. So for the names the following rules apply:
If the names contain characters other than letters, numbers, underscore (_) or colon (:), the column names must be enclosed individually in Accent Graves (e.g. `namespace.name`).
IF the following small XML file is given:
<pp.adrässe⸗1>
<pp.förma>
<pp.büro tür='12' >A 1</pp.büro>
</pp.förma>
<pp.förma>
<pp.büro tür='13' >A 2</pp.büro>
</pp.förma>
<pp.förma>
<pp.büro tür='14' >WERK II</pp.büro>
</pp.förma>
</pp.adrässe⸗1>
Then the following statement can be used to determine all addresses whose office adresses begin with A. Please note
that the attribute tür does not need (but of course may have) any quotation marks.
select `pp.büro`, `pp.büro`.tür node `pp.adrässe⸗1`.`pp.förma` where `pp.büro` like 'A%'
Element paths are composed from the element names downwards separated by periods (.). (One of the reasons for the `` quotation marks when a name contains dots).
Reference to the ID of a subobject
productdata.object.sub.id
Since v4.2 R32300 With the element name child_N (with N = {0, 1, ...}) you can access the (0-based) nth subelement of an element. The name of the subelement itself is ignored. Please note that attributes are counted like elements!
Reference to the ID of the fourth subobject
productdata.child_3.id
In the example row.child_0 points to row.num and row.child_3.name has the content 'B'.
<row ⓪ num="2" ① id="1"> ② <col name="A" num="1" id="0"> <format></format> <value>Government</value> <text>Government</text> </col> ③ <col name="B" num="2" id="1"> <format></format> <value>Canada</value> <text>Canada</text> </col> ...
Higher-level elements can be accessed by .. (tow dots). Three dots denotes two levels above and so on. The multiple dots are allowed only at the beginning of a column name.}
Access to the object above sub
..sub
In where conditions the . (dot) is replaced by the elements own content.
Given is the following XML structure:
<offer> <stylepromotion comet_id="228056984"> <productpanelname>Badmöbel "Elias"</productpanelname> <text keyname="PROMOTION_TEXT_PRINT">...</text> <text keyname="SHORT_DESCRIPTION">Badmöbel "Elias"</text> <text keyname="MATERIALDESC_FOR_STYLE">Kiefer</text> <keyattribute no="1" displayname="Möbeltyp">A_FURNITURE_TYPE</keyattribute> <keyattribute no="2" displayname="Farbe">A_COLOR</keyattribute> </stylepromotion> </offer>
With the following statement the displayname of a certain keyattribute can be queried. For A_FURNITURE_TYPE of the stylepromotion with the ID 228056984 thus "furniture type".
xmlget displayname node offer.stylepromotion where comet_id = 228056984 node keyattribute where . = "A_FURNITURE_TYPE"
Normally, a distinction between attributes and elements is not necessary. Only if there are attributes with the same name as direct subelements, a distinction must be made. In thius case, the attribute name is prefixed with @ (like attribute). Elements are marked with $. span[Deutlich]{If the marking is missing, the attributes are used.}
Distinguish between different ids of an object.
@id $id
CDATA blocks in the XML files are taken into account and restored when writing the files. If an element value is to be defined using CDATA, the methods xmlquery::send_cdata_begin and send_cdata_end or xmlquery::input with the type definition kCDATA can be used. span[Deutlich]{Inside CDATA blocks the string ![[[CDATA[ must not be used.}
The following description of the xmlwuery language is given is in so-called EBNF syntax. You can find a short description of EBNF here.
Statements start with the (optional) definition of the Function Variables. After that, the XML file on which the statement is to be executed is mandatorily expected. Then the actual statement follows:
A full path to the XML file is expected as file definition. The path may start with a defined Alias. In XML offline data connections, incomplete paths are also resolved relative to the current XML data folder.
Selects start with one of the (equivalent) keywords select or xmlget. Then a comma-separated list of result columns follows. Optionally, the results can be restricted with a prefixed distinct definition. After the results, you specify the XML path you want to search in. This path always starts at the root element of the given XML file. With an orderby-definition the results can be sorted to the final order.
With the help of the keyword distinct the results of a select can be reduced to unique results. To do this, add a distinct definition before the results list:
Hier einige Beipiele:
select distinct id, num, substr (t.value, 3, -1), ... // Eindeutig in [id, num, t.value] select distinct (t.value) id, num, substr (t.value, 3, -1), ... // Eindeutig in [t.value] select distinct (t.value, num) id, num, substr (t.value, 3, -1), ... // Eindeutig in [t.value, num] select distinct (t.value, num, abc.def) id, num, substr (t.value, 3, -1), ... // Die fehlende Spalte abc.def wird ignoriert
As results of a select you specify a comma-separated list of Element Paths and constant values (numbers and strings). The single results can additionally be processed by functions or with simple calculations:
Element Paths in result columns must always start at the last element reached by node-selectors. Parent nodes can be reached with the dot notation.
Element Paths and constants (integers, decimal numbers and strings) are allowed as values. Element paths start at the last element reached by the node-selectors. Parent nodes can be reached by the dot notation . In decimal numbers, dot (.) and comma (,) are accepted as decimal separators.
Simple calculations can be done in the return columns. The formulas may contain Element Paths whose current values are inserted before each calculation. The following operators are allowed :
Parentheses are not provided so far. To be able to distinguish between signs and operators, a space must be placed between + or - and the following value . The processing of the formulas is done strictly from left to right, all operators have the same precedence. If possible, results are represented as integers. Here are some examples:
1 + 2 * 3 = 9 // but not 7 1.1 + 1.8 = 2.900000 // but 1.1+1.9 = 3 (without decimal places) 2 * id || name = "24Name" // with id=12 and name="Name" 2 * id || name + 3.1 = 27.1 // with id=12 and name="Name", name is not convertible to a number, so it is 0
The following functions are available for calculating strings:
The same functions are also allowed for calculating the tags of the statement environment.
substr (name, 10, -1) token (name, 1, ".")
If an element or attribute of your XML file has one of the function names given above, this name must be enclosed in Accent Graves (`..`) in the call. E.g, instead of select filename node ... call select `filename` node ... .
node-Selectors determine the XML elements in which the statement should search. They each consist of an Element Path and a where condition.
The evaluation always starts at the root element of the XML structure and the node selectors must describe a continuous and existing element path . So the first selector always starts at the root element of the XML structure. Further node selectors can continue the element path.
The result columns start at the last element of the node selectors.
Given is the following XML structure:
<offer> <stylepromotion comet_id="228056984"> <productpanelname>Badmöbel "Elias"</productpanelname> <text keyname="PROMOTION_TEXT_PRINT">...</text> <text keyname="SHORT_DESCRIPTION">Badmöbel "Elias"</text> <text keyname="MATERIALDESC_FOR_STYLE">Kiefer</text> <keyattribute no="1" displayname="Möbeltyp">A_FURNITURE_TYPE</keyattribute> <keyattribute no="2" displayname="Farbe">A_COLOR</keyattribute> </stylepromotion> </offer>
With the following statement the displayname of a certain keyattribute can be queried. For A_FURNITURE_TYPE of the stylepromotion with the ID 228056984 thus "furniture type".
xmlget displayname node offer.stylepromotion where comet_id = 228056984 node keyattribute where . = "A_FURNITURE_TYPE"
Important note: xmlquery requires a fully defined XML structure to evaluate where conditions. Missing elements and attributes can be defined with dummy definitions in the xentities.
Conditions can be used to restrict the set of elements at the level of each node selector. Conditions can be parenthesized and combined with and and or. On the left side of the comparisons functions are allowed:
and and or are interpreted in the usual precedence and before or, A || B && C therfore means A || (B && C)
The result of a condition is determined by the respective comparison operator. The following applies:
Identifiers ending in id or sequencenr (case insensitive) or starting with id and have a number in the third position (such as id2 or id2Xid3) expecting integers as comparison values.
The configuration file xentities.xml can be used to specify the data type of elements, see here for more information.
At the end of the command, you can define a sorting by adding the keyword orderby followed by a comma-separated list of elementpaths and a (optional) sort order. If no sort order is given, the results are sorted ascending.
Only element paths which also appear in the result columns are allowed. Up to 10 sort fields may be specified:
Sorting is done according to the following criteria:
The example shows a simple select command that outputs the names and subIDs of all the product data whose subID is 1002.
select name, sub.id node productdata.object where id > 0 and sub.id = 1002;
The command corresponds to the syntax of the command \ with the difference that behind each result column there is a new value separated by '='. Only direct assignments are permitted for values. Assignments of the type id = id+1 are not implemented. Changes must be confirmed using commit.
The example shows a simple update command in respect of the name and subID of all Elements which are to be changed with the sub ID 1002.
update name="Hallo Hallo", sub.id=33333 node productdata.object where id > 0 and sub.id = 1002;
The command corresponds to the syntax of the command xmlget with the difference that behind each result column there is a new value separated by '='. For each Element found a copy will be created, and inserted into the existing structure. If precisely one data set is to be inserted, the where condition can be set so that precisely one data set can be selected, so for example where id = 0. If the copy is inserted, the defined columns will be filled with the values of the insert. New Elements can only be inserted in files which have at least one Element of the required structure. Changes must be confirmed using commit.
In the example a copy is made of all product data which contains sub-products with the id 1002, inserts a copy into the existing product data and changes the name and sub IDs of the new product data.
insert name="Hallo Hallo", sub.id=33333 node productdata.object where id > 0 and sub.id = 1002;
The command corresponds to the syntax of the command xmlget with the difference that no result columns are defined.. Changes must be confirmed using commit.
Delete all product data whicn contains sub-products with the id 1002.
delete node productdata.object where id > 0 and sub.id = 1002;
With commit all changes will be written back in the XML file. After commit changes can no longer be undone.
The following definitions may have specifications for files in which they are to apply. The following is valid for all file specifications in optimizations:
By creating an index, the processing of xmlqueries can be accelerated up to 20 times. The definition of an index is useful and supported for the following cases:
In the following three examples of where conditions, no index can be applied to name:
Indexes are defined in the file xindex.xml in the XML data folder and have the following format:
<indicees> <index> <file></file...> <nodepath>...</nodepath> <unique>no</unique> <!-- yes | no --> <enabled>yes</enabled> <!-- yes | no --> </index> </indicees>
The file path file defines the file in which the index is to be applied.
In nodepath the full XML path of the attribute to be indexed is specified. Path separator is the dot (.).
The attribute unique defines whether an index contains unique values (yes) or not (no). For unique indexes we can use the first found object. For non-unique indexes, all Elements of the same content are included in the selection.
With enabled the index can be disabled. Allowed are the values yes and no.
The example shows an index file.
<?xml version="1.0"?> <indicees>
<!-- Standard indexes --> <index> <file>panelstatements.xml</file> <nodepath>panelstatements.panelstatement.id</nodepath> <unique>yes</unique> <enabled>yes</enabled> </index> <index> <file>actions.xml</file> <nodepath>actions.action.classid</nodepath> <unique>no</unique> <enabled>yes</enabled> </index> <index> <file>pageitems.xml</file> <nodepath>pageitems.pageitem.id</nodepath> <unique>yes</unique> <enabled>yes</enabled> </index>
<!-- Fachinfo_6-digits_id.xml --> <index> <file>Fachinfo_[0-9]{6}_id.xml</file> <nodepath>Publication.ProductGroup.Product.ProductID</nodepath> <unique>yes</unique> <enabled>yes</enabled> </index> <index> <file>Fachinfo_[0-9]{6}_id.xml</file> <nodepath>Publication.ProductGroup.Product.ProductGroupID</nodepath> <unique>no</unique> <enabled>yes</enabled> </index>
</indicees>
In the file xentities.xml special import controls can be defined. The following control types are defined:
<?xml version="1.0"?> <entities></entities>
Text can contain formatting instructions which are defined in HTML or InDesign® tagged text, for example <B>my text</B>. The XML parser will interpret this text as sub-nodes of the current nodes and give it the content My text. In order to prevent such misinterpretations content can be replaced prior to the reading of the file. The replacements can be restricted to the individual files.
When defining the preparatory replacements, ensure that no valid XML tags of the file are replaced. Or, even better, when defining the XML-DTD refrain from using Element names which are used in HTML or InDesign® tagged text (such as <H1>, <TABLE> oder <P>)
<prereplace> <file></file> <search><b></search> <replace><cFont:Verdana></replace> </prereplace>
If this replacement is only to be used with data files indicated in the MYFILE, the following definitions can be used.
<prereplace> <file>$MYFILE</file> <search><b></search> <replace><cFont:Verdana></replace> </prereplace>
Replace defined text parts with others, e.g. replacing HTML-typical line delimiters (<BR>) with InDesign® line delimiters. The replacements are implemented directly upon iport of the XML files. The definition of the replacements can be limited to individual files. For the file paths, the alias names defined in the panel Settings can be used.
The following keywords will be automatically replaced by their current values in the replacement string replace :
The following example describes the definition which is required to replace all occurrences of AAAA.
<entity> <file></file> <search>AAAA</search> <replace>My Name</replace> </entity>
To get the names of the currently used XML files in the data file listed in MYFILE, the following definition can be used. Each AAAA in the data file can be replaced by the current data name.
<entity> <file>$MYFILE</file> <search>AAAA</search> <replace>$NAME</replace> </entity>
These replacements are only implemented after the text of an XML Elements in an InDesign® document has been implemented. They only apply to precisely defined placeholders. The background to these replacements is that, for example, the HTML specification <B> requires various replacements in connection with the target position in the InDesign® document. The definitions can be deactivated.
The following example describes the definitions required to translate a <B> in the placeholder 1 into a certain script style. Two definitions are required, for start and end tag.
Be aware that while you may indeed specify <b> as the value, this opened tag will be automatically replaced. But the closing tag (</b>) must be specified in XML-compatible syntax. Be ware, furthermore, that the definition of the script type (hier <cFont:Verdana>) may be specified as open tag in this script type, but not <cFont:Verdana Bold>, because Verdana Bold is not aq valid XML Element name because of the space.
When defining the file xentities.xml you should refrain from using the simple <>-script type and always use the parenthesis in the script style <>.
<placeholderrel> <plid>1</plid> <enabled>1</enabled> <search><b></search> <replace><cFont:Verdana></replace> <placeholderrel> </placeholderrel> <plid>1</plid> <enabled>1</enabled> <search></b></search> <replace><cFont:></replace> </placeholderrel>
The data type of Elements will be required for comparison and sorting. In the standard case, all Elements (case insensitive) which begin with id or sequence #, or which end with these terms, will be considered to be numbers, all other Elements are strings. With typedef Elements in the entity file this definitions can be changed. For the data path, the alias names defined in panel Settings can be used. Tha following values supported for type type
Identifiers which end with ID, are automatically read as numbers. In the following example it is shown that ProductID of the file products.xml should be processed as a character chain.
<typedef> <file>products.xml</file> <attr>ProductID</attr> <type>string</type> </typedef>
When importing the XML files, so-called dummy nodes can be created. The values of these nodes can be accessed in the standard method as if they were defined in XML files.
You specify the file, for which a definition is valid together with the parent node of the dummy. For the file path, the alias name defined in panel Settings can be used. No text Elements may be used for the parent node. The dummy will be defined with a name and a value. For values, the following specifications are required :
Description | Example | |
@any text | Use the text after the @. | @missing attribute
missing attribute |
[#]attributeName {attributeName} | Use the hash code of the content of attributeName. The attribute must be a direct sibling of the dummy. Versions prior
v3.3 R2711 are always using the hash value of the content.
since v3.3 R2712, 16. Nov. 2011 With a trailing # you will get the direct content instead of its hash code. since v3.3 R2712, 16. Nov. 2011 You may give a list of any number of attribute names here. The names must be delimited by one blank. The value of the first existing attribute is used as content of the dummy. | #author image price |
A user-defined number of dummies may be created for a parnent node.
Dummy nodes of the type lineno are suitable for ensuring the sorting sequence of the data sets in accordance their sequence in the XML file.
The following example creates the two sub-Elements myid and myid2 when importing the file products.xml in the Element products.product.grid. The first Element contains the current line number of the XML file, the second the number of the dummy node. The first node will be assumed upon commit in the file products.xml. The third definition creates an Element for each product node, the contents of which is arranged as far as possible on a one-to-one basis to a positive number.
<dummy> <file>products.xml</file> <attr>products.product.grid</attr> <name>myid</name> <type>lineno</type> <writable>1</writable> </dummy> <dummy> <file>products.xml</file> <attr>products.product.grid</attr> <name>myid2</name> <type>dummycounter</type> <writable>0</writable> </dummy> <dummy> <file>products.xml</file> <attr>products.product</attr> <name>myid</name> <type>name</type> <writable>0</writable> </dummy>
Placeholder objects are always supplemented with a so-called classID (integer). This number controls, among other things, if the menu commands in a panel are activated for loading and storing. So, for example, the command update the products of the text selectionl is only then active if a placeholder is actually selected with a product in the document.
It may also be the case the placeholders are supplemented with their own class IDs. In this case it is preferable to be also be able to process these placeholders by means of a defined panel. The classification can be arranged using <classmap>. The definitions are evaluated in the following cases :
In the following example, it is defined that all placeholders of the classes 4 and 400 can also be processed using the panel Product Pool (classID 3).
<classmap> <id>3</id> <map><id>4</id></map> <map><id>400</id></map> </classmap>
Each xmlquery is trailed by the path of the XML file to work on.
Get the ids and names of all domains.
"domain.xml" xmlget id, name node domains.domain where id < 0
Paths may begin with the standard prefixes $HOME, $DESKTOP, $DOCUMENTS, ... . Incomplete paths are always calculated relatively to the current data folder.
Using the panel Settings further aliases can be defined.
The aliases are defined in the file datafiles.xml. Incomplete aliasses are always calculated relatively to the current data folder. To ascertain the current assignments, the functions file::enable_datafile, file::setdatafile and file::getdatafile may be used.
Here is an example of a valid file. The alias MYFILE is defined four times. One entry is active. The first two definitions point to two files in the current XML data folder, the last to a file of the Desktop.
<?xml version="1.0"?> <datafiles> <datafile> <id>0</id> <path></path> <alias></alias> <description>no</description> <enabled>0</enabled> </datafile> <datafile> <id>1</id> <path>products.xml</path> <alias>MYFILE</alias> <description></description> <enabled>1</enabled> </datafile> <datafile> <id>2</id> <path>products2.xml</path> <alias>MYFILE</alias> <description></description> <enabled>0</enabled> </datafile> <datafile> <id>3</id> <path>$DESKTOP/products.xml</path> <alias>MYFILE</alias> <description></description> <enabled>0</enabled> </datafile> <datafiles>
Use panel Settings for changes on alias names used in xml queries.
Since v4.1.5 R24666 Plugnis and comet_pdf support XPATH 1.0 for reading data from XML files.
This software is based on pugixml library (http://pugixml.org). pugixml is Copyright (C) 2006-2018 Arseny Kapoulkine.
The integration of XPATH into the priint:comet software was done in the hope, to make your work easier. Please understand that the implementation may not not contain all features and functions of XPATH. For solving extremely special queries please use the functions of the module xmlnode.
The following functions are available in XPATH queries. Descriptions of these functions can be found in the relevant XPATH documentation, here's the link to mozilla.
To obtain data records with several result columns, results can be combined with |. Each partial expression results in its own result column. The output takes place in the same order as in the statement. Incomplete records are skipped.
Please note : All Elements of a result row must have exactly the same parent node in the XML data! Results from Elements of different parents must be obtained in multiple queries. (And if you want to collect the results of these different lists in result tuples, you also will find out why you have to make this restriction if you want to allow incomplete and unsorted Elements at the same time.)
Given be the following simple XML structure. The complete example can be found below.
&<a> <b> <d>A</d> <c>1</c> </b> <b> <c>2</c> </b> <b> <c>3</c> <d>C</d> </b> </a>
... and the statement
/a/b/c | /a/b/d
... then you will get the following results. The first data record is output in a different order than in the XML, because the order of the statement is observed. The second data record is skipped because it is incomplete.
1, A 3, C
The definition of XPATH obviously does not provide 'columns' with fixed values - the parts of a | statement must all be Elements of the XML structure. We have therefore included a small extension in our implementation: With the statement
static-value "string"
you may insert columns with fixed values in the results rows. If the static string contains a number, this value can (but does not have to) be retrieved as a number. You can use any number of static columns, but the statement must contain at least one variable column.
Add an additional second column with the fixed value 2024 to the above example:
/a/b/c | static-value "2024" | /a/b/d
This will give you the following results:
1, 2024, A 3, 2024, C
static XMLTree open(
char* path,
int autoCommit = 0,
int useTreeBuffer = 1,
int autoUpload = 0,
int isLocal = 0,
int parseImmediate = 0)
Open an file based XML tree. span[Deutlich]{The created tree must be closed again using close!}.
Name | Type | Default | Description |
Return | XMLTree | Created tree of the XML file 0 : Error - file not found or not valid XML |
|
path | String or char* | - | Complete path to the XML file. Aliasnames are allowed at the beginning of the path. Under XML Offline, SOAP- or AEM®, you can open configration XMLs like panelstatements.xml or actions.xml here too. |
autoCommit | int | 0 | Save changes automatically when the tree is closed? Please note that configuration data are available elsewhere in the plug-ins and changes to these data can lead to program errors! XML data read from a SOAP or AEM® connection do not have local files and autoCommit on these trees therefore has no effect. Use the parameter autoUpload for these trees. |
useTreeBuffer | int | 1 | The reading of XML files is a quite time-intensive process. Therefore read files can be buffered. Buffered XML data are released on logout time. |
autoUpload | int | 0 | Upload XML while closing the tree. The parameter only has an effect on XMLs loaded from a SOAP or AEM® connection! |
isLocal | int | 0 | In SOAP and AEM® connections, XML files are automatically loaded from the data source. To load local files, set the parameter to 1. The file path path must be a complete path in this case! |
parseImmediate | int | 0 | Parse tree immediately? Normally the tree is read in only when needed, because now it is not yet clear,
whether xmlquery or XPATH should be used as query language and both methods require different internal representations of the tree. 0 : No 1 : Yes |
Load the content of a placeholder from the current data file $DATAFILE. If the requested product is not found, a conditional text with an error description is inserted into the document.
#include "internal/types.h" #include "internal/text.h"
int main () { XMLTree tree = 0; char name [5000]; int found = 0;
strcpy (name, "");
tree = xmlquery::open("$DATAFILE");
xmlquery::send(tree, "select name node posters.poster where ID = ?"); xmlquery::input(tree, kInt, gRecordID); xmlquery::output(tree, kString, name);
xmlquery::exec(tree); while (xmlquery::fetch (tree)) found = 1;
xmlquery::close(tree);
if (!found) { strcpy (name, "%!TT<DefineCondition:ERRORCODE=<ConditionColor:1,0,0>"); strcat (name, "<ConditionIndicatorMethod:Highlight><ConditionVisibility:0>>"); strcat (name, "<cConditionalText:ERRORCODE>Product not found!<cConditionalText:>"); }
textmodel::replace (name);
return 0; }
Write the content of a placeholder HTML-formatted back to an XML file.
#include "internal/types.h" #include "internal/text.h"
int main () { String htmlText = string::alloc (); XMLTree tree = xmlquery::open ("$DATAFILE", 1, 1, 1);
html::export_frame (gFrame, &npsp; "kOutputBuffer", htmlText, &npsp; "kCSSEscapeMode", 1, &npsp; "kBodyOnly", 1, &npsp; "kEscapeBrackets", 0);
string::insert (htmlText, 0, "%!TT_html_");
xmlquery::send(tree, "update description = ? node books.productgroup where productgroupID = ? node book where bookID = ?"); xmlquery::input(tree, kString, htmlText); xmlquery::input(tree, kInt, 10); xmlquery::input(tree, kInt, 100);
xmlquery::exec(tree); xmlquery::close(tree);
return 0; }
static XMLTree parse(char* xml)
Read a string based XML tree. The resulting tree must be deleted with close!.
Name | Type | Default | Description |
Return | XMLTree | Resulting tree of the XML string 0 : error - string not valid xml |
|
xml | String or char* | - | Valid XML string. |
static int close(XMLTree tree, int doFlush = 0)
Closing an XML tree. The command must be made in respect of every XML tree created with xmlquery::open or xmlquery::parse.. If the tree was opened with autocommit, the tree is written to the file before closing.
Name | Type | Default | Description |
Return | int | 0 or ErrorCode | |
tree | XMLTree | - | Tree of XML file opened with xmlquery::open or xmlquery::parse. |
doFlush | int | 0 | Remove all Comet-internal data of the xml tree? 0 : no 1 : yes. Reparse the tree on next call to open. Flush is only done for xml files opened with useTreeBuffer set to 1. All XMLTrees of the file must be closed at flush-time. Flushing Comet standard files actions.xml, panelstatements.xml, ... is not allowed. |
static int send(XMLTree tree, char* cmd)
Send an XML instruction to ascertain values of an XML tree. Subsequent calls of xmlquery::send, xmlquery::isend and xmlquery::fsend supplement the XML instruction. The instruction is cleared after xmlquery::exec.
The statement can be written in xmlquery or XPATH.
XPATH is supported since v4.1.5 R24590.
Name | Type | Default | Description |
Return | int | 0: Error 1: Success |
|
tree | XMLTree | - | Representation of an XML file created with xmlquery::open or xmlquery::parse. |
cmd | String or char* | - | Instruction text |
The example shows two data queries, one in xmlquery and one in XPATH syntax of an XML file with the following content:
<a>
<b>
<d>A</d>
<c>1</c>
</b>
<b>
<c>2</c>
</b>
<b>
<c>3</c>
<d>C</d>
</b>
</a>
Both queries return the same result :
(1-A)
(3-C)
#include "internal/types.h" #include "internal/text.h" int main () { XMLTree tree; int tst; String s1 = string::alloc (); String s2 = string::alloc (); String s3 = string::alloc ();
tree = xmlquery::open ("$DESKTOP/abc.xml", 1, 1, 1);
for (tst = 0; tst < 2; tst++) { if (tst == 0) xmlquery::send (tree, "select c, d node a.b"); else if (tst == 1) xmlquery::send (tree, "/a/b/c | /a/b/d");
xmlquery::output (tree, kString, s1); xmlquery::output (tree, kString, s2);
xmlquery::exec (tree); if (tst == 0) frame::replace (gFrame, "%!TT<ParaStyle:>xmlquery<ParaStyle:>"); else frame::append (gFrame, "%!TT<ParaStyle:><ParaStyle:>XPATH<ParaStyle:>");
while (xmlquery::fetch (tree)) { string::set (s3, "%%!TT<ParaStyle:> (%s-%s)\n", s1, s2); frame::append (gFrame, s3); } }
xmlquery::close (tree);
return 0; }
static int send_cdata_begin(XMLTree tree)
Open a CDATA block inside a xmlquery. The statement has the same effect as xmlquery::send ("<![CDATA["). You can use
this call inside values that are defined as to be CDATAs too. You have to close an open CDATA block by calling
send_cdata_end
Do not use the string ![[[CDATA[ inside a CDATA block.
Name | Type | Default | Description |
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
static int send_cdata_end(XMLTree tree)
Close a CDATA block inside a xmlquery. The statement has the saqme effect as xmlquery::send (]]>"). You can use this call inside values that are defined as to be CDATAs too.
Name | Type | Default | Description |
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
static int isend(XMLTree tree, int i)
Send an integer to an XML instruction. The command has a similar effect as xmlquery::send with the difference that the number is appended to the instruction as text.
Name | Type | Default | Description |
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
i | int | - | Integer which is to be appended to the XML instruction. |
static int fsend(XMLTree tree, float f)
Send a decimal number to an XML instruction. he command has a similar effect as xmlquery::send with the difference that the decimal number is appended to the instruction as text. The precision of floats is limited to 6 numbers.
Name | Type | Default | Description |
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
f | float | - | Decimal number which is to be appended to the XML instruction. |
static int input(
XMLTree qu,
int type,
char* value)
Connect a value to the corresponding value placeholder in the SQL command.
The value is inserted in the command directly. Variables are not buffered until execution.
The specification of the second parameter is mandatory and must match the data type of the associated attribute.
Name | Type | Default | Description |
Return | int | 1 = Okay 0 = Error |
|
tree | XMLTree | - | A tree opened with xmlquery::open. |
type | int | - | Type of value. The data type, which belongs to a
variable placeholder, is derived from the respective instruction.
It is the task of the script programmer to connect
the value types. kInt kFloat The precision of floats is limited to 6 numbers. kString kCDATA |
value | depends | - | This value will be sent to the database in place of the associated variable placeholder (?).
Non matching pairs can cause InDesign crashes or invalid data on your data base. kInt: int, short, long (z.B -1, 0, 1, 2) kFloat : float, real (z.B. -1.0, 1.0, 1.1), The precision of floats is limited to 6 numbers. kString : String or char* (for instance "", "paul") kCDATA : String or char* (for instance "", "paul") |
Where the following command is sent
select name, age, cv node persons.person where name like ? and age > ?
Then input connections of the following type are expected:
xmlquery::input (tree, \spaqn[keyword]{kString}, "Paul%"); xmlquery::input (tree, kInt, 10);
static int output(
XMLTree tree,
int type,
int* pointer)
xmlquery_output Allocating variables to the results column of an XML instruction. This allocates the result
of the first result column to the first linked variable and so on.. because XML files
do not contain type information, the type of result column is user-defined in the sense that
the column value can only be converted in the target type. If the XML files receives a decimal number, for example,
the corresponding column can be linked to strings, integers or decimal numbers.
The instruction requires the Include
#include "internal/types.h"
The allocation of variables to the results column can be carried out before or after xmlquery::exec. If xmlquery::fetch finds no other results, the allocation is cancelled.
Name | Type | Default | Description |
Return | int | 1: Okay 0: Error |
|
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
type | int | - | Data types of the following variables are follows : kInt : pointer to an integer kFloat : pointer to a decimal numberl kString : String oder char*-Variable. When the type is char*, the variable must have sufficient reserved memory. |
pointer | int*, float*, String or char* | - | Target variable as described above. |
allocatedSize | int | 0 | Size of the reserved memory for string results. When pointer is of type String, this parameter is ignored Too little memory for the string results is very often the cause for script failures that are difficult to trace. With the specification of the maximum length of the strings, it is ensured that it will only be stored in reserved memory areas. Results, where required, will be limited to the specified length. The memory length contains a byte for the string ending 0. 0 : If the specification is missing or is 0, the returned values will be completely inserted in the target variable without a check of the length. |
static int exec(XMLTree tree, int showErrors = 0)
Executing the XML instructions. The call automatically resets the XML instruction of the query.
Name | Type | Default | Description |
Return | int | 1 : Okay 0 : Error You may use the functions xmlquery::error and xmlquery::errnum to get more information about the result. |
|
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
showErrors | int | 1 | Is the processing error to be automatically displayed? 0 - Do not show error in an error dialog. The script undertakes the error management itself. otherwise - display standard error dialog A complete list of possible errors you can find here. Please notice, that missing attributes or Elements are not errors. To catch missing nodes messages please use here. |
static int fetch(XMLTree tree)
Get the next result column of the XML instruction. Before fetching the result the columns must be bound to variables (see xmlquery::output). If xmlquery::fetch does not find any other results, the bindings are cancelled.
Name | Type | Default | Description |
Return | int | 1 result found 0 no other results. The fixed variable bindings are cancelled using xmlquery::output. |
|
tree | Representation of an XML file created with xmlquery::open. |
static int error(XMLTree tree, char* mess)
Error description of the last XML instruction execution. A complete list of possible errors you can find here.
Please notice, that missing attributes or Elements are not errors but only warnings. To catch warnings please use xmlquery::get_exec_infos.
Name | Type | Default | Description |
Return | String or char* | (Depends on parameter str) Error description of the last XML instruction execution, same as parameter mess. | |
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
mess | String or char* | - | Reserved memory for the error message (at least 256 bytes when using char*) |
static int errnum(XMLTree tree)
Error code of the last XML instruction execution.
Please notice, that missing attributes or Elements are not errors. To catch missing nodes messages please use xmlquery::get_exec_infos.
Error codes of XML queries
Nr. | description |
0 | no error |
-43 | File not found or incorrect |
1 | Index must not point to the root Element. |
2 | xmlset : Error while changing values. |
3 | xmlinsert : Error while setting values. |
4 | Empty xmlget command. |
5 | Keyword xmlget, xmlset, xmlinsert or xmldelete missing. |
6 | Unexpected end of xmlget. |
7 | There should never be a where without a node. |
8 | Missing value in xmlset/xmlinsert, must be of type int, real or string. |
9 | Missing '|'. |
10 | There must be a where before the next node. |
11 | There should never be a where without a node. |
12 | Orderby is the last key word. |
15 | Orderby failed, column must be in the result xmlcolumns. |
16 | xmlcommit : Cannot write empty xml tree. |
17 | xmlcommit : Writing file failed. |
Warnings of XML queries
Nr. | Beschreibung |
0 | Keine Warnungen und Fehler |
1290 | Node nodeName used in columns not found. |
1293 | Error on traversing nodes while creating index. |
1299 | Node nodeName used in where not found. |
Name | Type | Default | Description |
Return | int | Error code of the last XML instruction execution. | |
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
static int get_exec_infos(XMLTree tree, char* warnings)
Does a xml query produce some warnings or errors? The function will catch the warnings and errors of the last statement executed on a given XMLTree.
Name | Type | Default | Description |
Return | int | Last result code of the last statement execute on a XMLTree 0 : Okay otherwise : see here |
|
tree | XMLTree | - | Representation of an XML file created with xmlquery::open. |
warnings | String or char* | 0 | result string for warnings and errors 0 : ignore otherwise :Allocated memory for the warnings and errors (at least 4096 Bytes when using char*) |
XMLTree tree = xmlquery::open ...;
char execInfos [4096];
:
:
xmlquery::exec (tree);
if (xmlquery::get_exec_infos (execInfos)
{
showmessage("XMLError %s", execInfos);
}
static int app_path(char* p)
Ascertain the current program path to the iQuest Comet XML data files. This folder in set up globally in InDesign® and contains, inter alia, the file placeholder.xml and the folder actions, with which the placeholders and their actions are defined.
Name | Type | Default | Description |
Return | String or char* | (Depends on parameter p) Current program path to the iQuest Comet XML data files, same as parameter p | |
p | String or char* | - | Reserved memory for the result. |
char p[4069];
showmessage ("%s", xmlquery::app_path (p));
static XMLTree process(
char* destinationPath,
char* definition,
long serviceId = -1,
long sourceId = -1,
int force = 0)
Generate an XML file (and/or an internal representation) from a given Service definition.
Name | Type | Default | Description |
Return | XMLTree | new generated XML tree | |
destinationPath | String or char* | - | destination path for the XML file "" : Do not create an XML file |
definitionPath | String or char* | - | Path to the definition file |
serviceId | int | -1 | ID of service -1 : first available |
sourceId | int | -1 | ID of source -1 : first available |
force | int | 0 | Force (re)reading 0 : Check whether an XML file already exists and is up to date |
static char* serialize(XMLTree tree, char* buffer)
Serialize an XML tree. The result is copied to buffer. When buffer is of type char*, enough memory has to be allocated.
Name | Type | Default | Description |
Return | String or char* | (Depends on parameter buffer) XML-string, same as parameter buffer | |
tree | XMLTree | - | Tree opened by xmlquery::open. |
buffer | String or char* | - | Allocated memory for the result. |
static int write(XMLTree tree, char* destPath)
Write an XML tree to a file.
Name | Type | Default | Description |
Return | int | 0 or ErrorCode. | |
tree | XMLTree | - | Tree opened by xmlquery::open. |
destPath | String or char* | - | Path to output file |
static char* to_json(
XMLTree tree,
char* entryPoint = "",
char* subValue = "")
Create a JSON string of an XML tree or parts of it.
Name | Type | Default | Description | |||||||||
Return | char* | JSON string (of the parts) of the XML tree or "" in case of error. The return value is read only, do NOT CHANGE. The result will be overridden on following calls to the function. See here to learn more about functions returning r/o char* values. |
||||||||||
entryPoint | String oder char* | - | Valid path to a substructure of the tree "" : Whole tree |
|||||||||
subValue | String oder char* | - |
Selection criterion for sub elements or "" for all sub elements. name operator value If the element to be exported has no subelement or attribute of the given name, the criterion is ignored and the element is exported.
|
Write all Comet Groups of the meta data export groups.xml whose ID contains 89 into a JSON.
int main () { XMLTree tree; char * json; int fi;
tree = xmlquery::open ("$DESKTOP/groups.xml", 0, 1, 0, 0, 1); json = xmlquery::to_json (tree, "/psc:grouplist/groups/group", "id ? '%89%'"); xmlquery::close(tree);
fi = file::open ("$DESKTOP/groups.json", "w"); file::write (fi, json); file::close (fi);
return 0; }
static int flush(char* xmlPath)
Remove any Comet internal data for the given XML file. The file is reparsed on the next call to open.
Flush is only done for xml files opened with useTreeBuffer set to 1. All XMLTrees of the file must be closed at flush-time. Flushing Comet standard files like actions.xml, panelstatements. xml, ... is not allowed.
Name | Type | Default | Description |
Return | int | 0 or ErrorCode | |
xmlPath | String or char* | - | Complete path to the XML file |
Schreibe alle Cometgruppen des Meatdsaten-Exported groups.xml, deren ID 89 enthält, in ein JSON.
int main () { XMLTree tree; char * json; int fi;
tree = xmlquery::open ("$DESKTOP/groups.xml", 0, 1, 0, 0, 1); json = xmlquery::to_json (tree, "/psc:grouplist/groups/group", "id ? '%89%'"); xmlquery::close(tree);
fi = file::open ("$DESKTOP/groups.json", "w"); file::write (fi, json); file::close (fi);
return 0; }
Alphabetic index HTML hierarchy of classes or Java