2 * Copyright (c) 1995-2000, Index Data.
3 * See the file LICENSE for details.
5 * d1_if.c : A simple interface for extracting strings from data1_node
9 * Revision 1.5 2000-02-10 13:42:43 adam
10 * Removed C++ comment.
12 * Revision 1.4 2000/01/06 14:30:56 adam
13 * Minor change - to prevent warnings.
15 * Revision 1.3 2000/01/06 11:27:02 adam
16 * Minor fix so that this source compiles using Visual C++.
18 * Revision 1.2 2000/01/04 17:46:17 ian
19 * Added function to count occurences of a tag spec in a data1 tree.
21 * Revision 1.1 1999/12/21 14:16:19 ian
22 * Changed retrieval module to allow data1 trees with no associated absyn.
23 * Also added a simple interface for extracting values from data1 trees using
24 * a string based tagpath.
33 #include <yaz/data1.h>
40 * Search for a token in the supplied string up to the supplied list of stop characters or EOL
41 * At the end, return the character causing the break and fill pTokenBuffer with the token string so far
42 * After the scan, *pPosInBuffer will point to the next character after the one causing the break and
43 * pTokenBuffer will contain the actual token
45 char data1_ScanNextToken(char* pBuffer,
48 char* pWhitespaceChars,
51 char* pBuff = pTokenBuffer;
54 while ( **pPosInBuffer )
56 if ( strchr(pBreakChars,**pPosInBuffer) != NULL )
58 /* Current character is a break character */
60 return *((*pPosInBuffer)++);
64 if ( strchr(pWhitespaceChars, **pPosInBuffer) != NULL )
67 *pBuff++ = *((*pPosInBuffer)++);
71 *pBuff++ = *((*pPosInBuffer)++);
72 return(**pPosInBuffer);
76 * Attempt to find a string value given the specified tagpath
78 * Need to make this safe by passing in a buffer.....
81 char *data1_getNodeValue(data1_node* node, char* pTagPath)
85 n = data1_LookupNode(node, pTagPath );
89 /* n should be a tag node with some data under it.... */
92 if ( n->child->which == DATA1N_data )
94 return n->child->u.data.data;
98 yaz_log(LOG_WARN,"Attempting to lookup data for tagpath: Child node is not a data node");
103 yaz_log(LOG_WARN,"Found a node matching the tagpath, but it has no child data nodes");
108 yaz_log(LOG_WARN,"Unable to lookup a node on the specified tag path");
115 /* Max length of a tag */
116 #define MAX_TAG_SIZE 50
119 * data1_LookupNode : Try and find a node as specified by a tagpath
121 data1_node *data1_LookupNode(data1_node* node, char* pTagPath)
123 /* Node matching the pattern in the tagpath */
124 data1_node* matched_node = NULL;
126 /* Current Child node as we search for nodes matching the pattern in the tagpath */
127 data1_node* current_child = node->child;
129 /* Current position in string */
130 char* pCurrCharInPath = pTagPath;
133 char Buffer[MAX_TAG_SIZE];
135 /* The tag type of this node */
138 /* for non string tags, the tag value */
141 /* for string tags, the tag value */
142 char StringTagVal[MAX_TAG_SIZE];
144 /* Which occurence of that tag under this node */
147 /* Character causing a break */
150 StringTagVal[0] = '\0';
152 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",[(."," ", Buffer);
156 /* Next component in node value is [ TagType, TagVal, TagOccurence ] */
157 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ","," ", Buffer);
158 iTagType = atoi(Buffer);
160 /* Occurence is optional... */
161 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ",]."," ", Buffer);
164 strcpy(StringTagVal,Buffer);
166 iTagValue = atoi(Buffer);
168 /* If sepchar was a ',' there should be an instance */
171 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "]."," ", Buffer);
172 iOccurences = atoi(Buffer);
177 /* See if we can scan the . for the next component or the end of the line... */
178 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
182 yaz_log(LOG_FATAL,"Node does not end with a ]");
189 /* We have a TagName so Read up to ( or . or EOL */
191 strcpy(StringTagVal,Buffer);
195 /* Read the occurence */
196 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, ")"," ", Buffer);
197 iOccurences = atoi(Buffer);
199 /* See if we can find the . at the end of this clause */
200 sepchr = data1_ScanNextToken(pTagPath, &pCurrCharInPath, "."," ", Buffer);
205 yaz_log(LOG_DEBUG,"search node for child like [%d,%d,%s,%d]",iTagType,iTagValue,StringTagVal,iOccurences);
208 /* OK.. We have extracted tagtype, Value and Occurence, see if we can find a node */
209 /* Under the current parent matching that description */
211 while ( ( current_child ) && ( matched_node == NULL ) )
213 if ( current_child->which == DATA1N_tag )
217 if ( ( current_child->u.tag.element == NULL ) &&
218 ( strcmp(current_child->u.tag.tag, StringTagVal) == 0 ) )
222 /* Everything matched, but not yet found the
223 right occurence of the given tag */
228 /* We have matched a string tag... Is there more to
230 matched_node = current_child;
234 else /* Attempt to match real element */
236 yaz_log(LOG_WARN,"Non string tag matching not yet implemented");
239 current_child = current_child->next;
243 /* If there is more... Continue */
244 if ( ( sepchr == '.' ) && ( matched_node ) )
246 return data1_LookupNode(matched_node, pCurrCharInPath);
256 data1_CountOccurences
258 Count the number of occurences of the last instance on a tagpath.
260 @param data1_node* node : The root of the tree we wish to look for occurences in
261 @param const char* pTagPath : The tagpath we want to count the occurences of...
264 int data1_CountOccurences(data1_node* node, char* pTagPath)
267 data1_node* n = NULL;
268 data1_node* pParent = NULL;
270 n = data1_LookupNode(node, pTagPath );
274 ( n->which == DATA1N_tag ) &&
277 data1_node* current_child;
280 for ( current_child = pParent->child;
282 current_child = current_child->next )
284 if ( current_child->which == DATA1N_tag )
286 if ( current_child->u.tag.element == NULL )
288 if ( ( n->u.tag.tag ) &&
289 ( current_child->u.tag.tag ) &&
290 ( strcmp(current_child->u.tag.tag, n->u.tag.tag) == 0 ) )
295 else if ( current_child->u.tag.element == n->u.tag.element )
297 /* Hmmm... Is the above right for non string tags???? */