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:

FUNCVARS XMLFILE \n \r \r\n SELECT INSERT DELETE COMMIT

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.

select xmlget DISTINCT RESULTCOL , SELECTORS ORDERBY

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:

distinct ( NODEPATH , )

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:

VALUE OPER FUNCTION

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.

NODEPATH CONSTANT

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:

lower upper trim reverse folder file filename shortfilename extender ( VALUE substr rsubstr ( VALUE , INT , INT token ( VALUE , INT , STRING )

Again, only simple calls are allowed. In particular, the parameters of the functions must not contain any further calculations.

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.

node NODEPATH where CONDITIONS

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:

VALUE FUNCTION REL_OP VALUE ( CONDITIONS ) and or CONDITIONS

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.

= =! < > <> like

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:

orderby NODELIST asc_int desc_int asc_float desc_float asc_string desc_string asc_ustring desc_ustring asc_datetime desc_datetime

Sorting is done according to the following criteria:

  1. Columns with the (case insensitive) names "Date" or "Datum" are sorted as date/time
  2. According to the data type of the column specified in the type definitions.
  3. Columns with the (case insensitive) names "Id" or "Sequencenr" are sorted as integers
  4. Alphabetical sorting. Leading integers or commas are compared as numerical values. The decimal separator is expected as decimal separator. The texts thus get the order
Since v3.4 R5130 The criteria how columns should be sorted can be overridden with the following specifications:

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:

  1. Preparatory text replacements
  2. Global text replacements
  3. Placeholder-relative text replacements
  4. Type definitions
  5. Dummy Elements
  6. ClassIDs
Each of the definitions are optional. Here the basics structure of the file:

<?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>&lt;b&gt;</search>
 	<replace>&lt;cFont:Verdana&gt;</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>&lt;b&gt;</search>
 	<replace>&lt;cFont:Verdana&gt;</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 (&lt;/b&gt;) 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 &lt;&gt;.

<placeholderrel>
 	<plid>1</plid>
 	<enabled>1</enabled>
 	<search>&lt;b&gt;</search>
 	<replace>&lt;cFont:Verdana&gt;</replace>
<placeholderrel>
</placeholderrel>
 	<plid>1</plid>
 	<enabled>1</enabled>
 	<search>&lt;/b&gt;</search>
 	<replace>&lt;cFont:&gt;</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 :

Prior to inserting the nodes, a check is made if a node with the desired name is already in existence. In this case no dummy will be created. Dummy definitions can furthermore defined whether with commit you should write in the XML file or not.

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
#include "internal/types.h"

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; }

Version 1.1.7, Januar 2005
autoCommit and useTreeBuffer since Version 1.1.9, 1 April 2004
autoUpload sinse v4.1 R22423, 30. Apr 2018
isLocal since v4.1.7 R26842, 22. Apr 2020
parseImmediate since v4.2 R31950, 30. Nov 2022

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::close
comet.xmltree.open

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.

Version 1.4.1 15. Juni 2007

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

comet.xmltree.parse

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.

Version 1.1.7, January 2005
doFlush seit v3.2.1 R2345, 9. März 2011

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::open

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; }

Version 1.1.7, January 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::isend
xmlquery::fsend
xmlquery::exec
comet.CXMLTree.send

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.

Version 1.4 R343 (30. May 2007)

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

comet.CXMLTree.sendCDataBegin

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.

Version 1.4 R343 (30. May 2007)

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

comet.CXMLTree.sendCDataEnd

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.

Version 1.1.7, January 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::send
xmlquery::fsend
xmlquery::exec
comet.CXMLTree.send

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.

Version 1.1.7, January 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::send
xmlquery::isend
xmlquery::exec
comet.CXMLTree.send

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")
#include "internal/types.h"

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);

Version 1.4 R366, 6.6.2007

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

comet.CXMLTree.input

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.
#include "internal/types.h"

Version 1.1.7, January 2005
allocatedSize since version 1.2.2, 17th October 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::open
comet.CXMLTree.output

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.

Version 1.1.7, January 2005
showErrors seit Version 1.2.2 (18. Oktober 2005)

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::open
xmlquery::send
xmlquery::fetch
xmlquery::error
xmlquery::errnum
xmlquery::get_exec_infos
comet.CXMLTree.execute

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.    

Version 1.1.7, January 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::open
xmlquery::output
comet.CXMLTree.fetch

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*)

Version 1.1.7, January 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::exec
xmlquery::errnum
xmlquery::get_exec_infos

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.

Version 1.2.2 (18 October 2005)

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::exec
xmlquery::error

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);
}

v3.4 R4617, 21. Okt. 2013

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

xmlquery::exec
xmlquery::error
xmlquery::errnum

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));

Version 1.1.7, January 2005

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

system::app_path

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

Version 1.4, Januar 2007

priint:comet InDesign® Plug-Ins, comet_pdf

xml_import

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.

Version 1.4, Januar 2008

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

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

Version 1.4, Januar 2008

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

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.

The selection criterion is applied exclusively to direct subelements or attributes of the entry level and must have the following syntax:

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.

Operator Description Example
=
==
<
<=
>
>=
!=
<>
Integer and floating number comparison

Export only subelements with id >= 1000.

id >= 1000

?
!

TText comparison. The search text must be given in quotation marks. Use ? for case-insensitive comparisons and ! or case-sensitive comparisons. With the empty string ('') as search text the criterion is ignored.

At the beginning and end of the search string % are allowed as wildcards. With \% the wildcard is ignored.

Export only sub-elements whose names start with "Article ".

name ? 'Article %'

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; }

v4.2 R31950, 30. Nov 2022

priint:comet InDesign® Plug-Ins

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; }

Version 3.2.1 R2345, 9. März 2011

priint:comet InDesign® Plug-Ins, comet_pdf, Illustrator

close

#include "internal/types.h"

Matthias Seidel, Gabi Siegert
Version 1.1.7, January 2005

Alphabetic index HTML hierarchy of classes or Java