Skip to content

Commit 31cbd0d

Browse files
author
Gerit Wagner
committed
revise wos serializer
1 parent 9ea9e1d commit 31cbd0d

File tree

2 files changed

+24
-42
lines changed

2 files changed

+24
-42
lines changed

search_query/wos/serializer.py

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,50 +15,32 @@
1515
# https://images.webofknowledge.com/images/help/WOS/hs_wos_fieldtags.html
1616

1717

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."""
2020

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}"
3725

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}")
4033
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)
5137

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})"
5941

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})"
6345

64-
return result
46+
return joined

test/test_query_translation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def test_translation_wos_part(query_setup: dict) -> None:
6767

6868
def test_translation_wos_complete(query_setup: dict) -> None:
6969
query_complete = query_setup["query_complete"]
70-
expected = '(TI=("AI" OR "Artificial Intelligence") AND TI=("health care" OR medicine) AND AB=(ethic* OR moral*))'
70+
expected = 'TI=("AI" OR "Artificial Intelligence") AND TI=("health care" OR medicine) AND AB=(ethic* OR moral*)'
7171
translated_query = query_complete.translate(PLATFORM.WOS.value)
7272
assert translated_query.to_string() == expected
7373

0 commit comments

Comments
 (0)