|
15 | 15 | # https://images.webofknowledge.com/images/help/WOS/hs_wos_fieldtags.html |
16 | 16 |
|
17 | 17 |
|
18 | | -def to_string_wos(query: Query) -> str: |
19 | | - """Serialize the Query tree into a WoS search string.""" |
| 18 | +def to_string_wos(query: Query, wrap: bool = False) -> str: |
| 19 | + """Serialize the Query tree into a Web of Science (WoS) search string.""" |
20 | 20 |
|
21 | | - result = "" |
22 | | - for child in query.children: |
23 | | - if child.operator: |
24 | | - # query is operator query |
25 | | - if child.value == Operators.NOT: |
26 | | - # current element is NOT Operator -> no parenthesis in WoS |
27 | | - result = f"{result}{to_string_wos(child)}" |
28 | | - |
29 | | - elif (child == query.children[0]) & (child != query.children[-1]): |
30 | | - result = ( |
31 | | - f"{result}" |
32 | | - f"{query.search_field.value if query.search_field else ''}" |
33 | | - f"({to_string_wos(child)}" |
34 | | - ) |
35 | | - else: |
36 | | - result = f"{result} {query.value} {to_string_wos(child)}" |
| 21 | + # Leaf node |
| 22 | + if not query.children: |
| 23 | + field = query.search_field.value if query.search_field else "" |
| 24 | + return f"{field}{query.value}" |
37 | 25 |
|
38 | | - if (child == query.children[-1]) & (child.value != Operators.NOT): |
39 | | - result = f"{result})" |
| 26 | + parts = [] |
| 27 | + for child in query.children: |
| 28 | + if child.operator and child.value == Operators.NOT: |
| 29 | + # Special handling: inject "NOT ..." directly |
| 30 | + not_child = child.children[0] |
| 31 | + not_str = to_string_wos(not_child, wrap=True) |
| 32 | + parts.append(f"NOT {not_str}") |
40 | 33 | else: |
41 | | - # query is not an operator |
42 | | - if (child == query.children[0]) & (child != query.children[-1]): |
43 | | - # current element is first but not only child element |
44 | | - # -->operator does not need to be appended again |
45 | | - result = ( |
46 | | - f"{result}" |
47 | | - f"{query.search_field.value if query.search_field else ''}" |
48 | | - f"({child.search_field.value if child.search_field else ''}" |
49 | | - f"{child.value}" |
50 | | - ) |
| 34 | + parts.append(to_string_wos(child, wrap=True)) |
| 35 | + |
| 36 | + joined = f" {query.value} ".join(parts) |
51 | 37 |
|
52 | | - else: |
53 | | - # current element is not first child |
54 | | - result = ( |
55 | | - f"{result} {query.value} " |
56 | | - f"{child.search_field.value if child.search_field else ''}" |
57 | | - f"{child.value}" |
58 | | - ) |
| 38 | + if wrap: |
| 39 | + field = query.search_field.value if query.search_field else "" |
| 40 | + return f"{field}({joined})" |
59 | 41 |
|
60 | | - if child == query.children[-1]: |
61 | | - # current Element is last Element -> closing parenthesis |
62 | | - result = f"{result})" |
| 42 | + # Top-level: wrap=False |
| 43 | + if query.search_field and all(not c.search_field for c in query.children): |
| 44 | + return f"{query.search_field.value}({joined})" |
63 | 45 |
|
64 | | - return result |
| 46 | + return joined |
0 commit comments