Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 103 additions & 52 deletions packtools/sps/formats/sps_xml/ref.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,93 @@
"""
data = {
"ref-id": "B1",
"label": "1",
"mixed-citation": "Aires M, Paz AA, Perosa CT. Situação de saúde...",
"publication-type": "journal",
"article-title": "Situação de saúde e grau de...",
"chapter-title": "The epidemiology of idiopathic inflammatory bowel disease.",
"source": "Rev Gaucha Enferm",
"edition": "4th ed",
"publisher-loc": "Rio de Janeiro",
"publisher-name": "Universidade Federal do Paraná",
"volume": "30",
"issue": "3",
"data-title": "Estudos de genes em ratos albinos na América Latina",
"version": "23 jan.",
"series": "Second International Workshop",
"day": "22",
"month": "10",
"year": "2009",
"fpage": "192",
"lpage": "199",
"ext-link": [
{
"ext-link-type": "uri",
"xlink:href": "http://socialsciences.scielo.org",
"text": "http://socialsciences.scielo.org"
}
]
"pub-ids": [
{
"pub-id-type": "pmid",
"text": "15867408"
}
]
"dates-in-citation": [
{
"content-type": "updated",
"text": "2006 Jul 20"
}
]
}

"""

import xml.etree.ElementTree as ET


def build_ref(data):
def build_ref(data, node=None):
"""
Builds an XML element representing a bibliographic reference.

Args:
data (dict): A dictionary containing reference details with the following structure:
- "ref-id" (str): Unique identifier for the reference (required).
- "label" (str): Label for the reference, e.g., "1" (optional).
- "mixed-citation" (str): Mixed content citation text (optional).
- "publication-type" (str): Type of publication, e.g., "journal", "book" (required).
- Additional bibliographic keys (optional):
- "article-title", "chapter-title", "source", "edition", "publisher-loc",
"publisher-name", "series", "day", "month", "year", "volume", "issue",
"data-title", "version", "fpage", "lpage".
- "ext-link" (list): A list of dictionaries, each containing:
- "ext-link-type" (str): Type of external link (e.g., "uri") (required).
- "xlink:href" (str): URL or URI of the external link (required).
- "text" (str): Display text for the link (optional).
- "pub-ids" (list): A list of dictionaries, each containing:
- "pub-id-type" (str): Type of publication ID (e.g., "pmid") (required).
- "text" (str): Value of the publication ID (required).
- "dates-in-citation" (list): A list of dictionaries, each containing:
- "content-type" (str): Type of date, e.g., "updated" (required).
- "text" (str): Date value in text format (required).
node (dict, optional): A dictionary containing additional XML elements to include in
the reference. For example:
- "person-group" (list): A list of XML elements representing authors or editors.

Returns:
xml.etree.ElementTree.Element: An XML element representing the reference.

Raises:
ValueError: If required fields are missing, including:
- "ref-id".
- "publication-type".
- "ext-link-type" and "xlink:href" for external links.
- "pub-id-type" for publication IDs.
- "content-type" for dates in citation.

Example input:
data = {
"ref-id": "B1",
"label": "1",
"mixed-citation": "Aires M, Paz AA, Perosa CT. Situação de saúde...",
"publication-type": "journal",
"article-title": "Situação de saúde e grau de...",
"source": "Rev Gaucha Enferm",
"volume": "30",
"issue": "3",
"fpage": "192",
"lpage": "199",
"ext-link": [
{
Copy link
Copy Markdown
Member

@robertatakenaka robertatakenaka Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rossi-Luciano considere adicionar <comment/>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"comment": "Disponível em: ",
"ext-link-type": "uri",
"xlink:href": "http://example.com",
"text": "http://example.com"
}
],
"pub-ids": [
{
"pub-id-type": "pmid",
"text": "12345678"
}
]
}
node = {
"person-group": [ET.Element("person-group", attrib={"person-group-type": "author"})]
}

Example output:
<ref id="B1">
<label>1</label>
<mixed-citation>Aires M, Paz AA, Perosa CT. Situação de saúde...</mixed-citation>
<element-citation publication-type="journal">
<article-title>Situação de saúde e grau de...</article-title>
<source>Rev Gaucha Enferm</source>
<volume>30</volume>
<issue>3</issue>
<fpage>192</fpage>
<lpage>199</lpage>
<ext-link ext-link-type="uri" xlink:href="http://example.com">http://example.com</ext-link>
<pub-id pub-id-type="pmid">12345678</pub-id>
<person-group person-group-type="author" />
</element-citation>
</ref>
"""
if not (id_text := data.get("ref-id")):
raise ValueError("attribute ref-id is required")

Expand All @@ -63,6 +104,10 @@ def build_ref(data):
ref_elem, "element-citation", attrib={"publication-type": publication_type}
)

if node:
for person_group in node.get("person-group") or []:
element_citation_elem.append(person_group)

basic_keys = (
"article-title",
"chapter-title",
Expand Down Expand Up @@ -92,12 +137,18 @@ def build_ref(data):
if not ext_link_type or not xlink_href:
raise ValueError("ext-link-type and xlink:href are required")

if ext_link_text := ext_link.get("text"):
ET.SubElement(
element_citation_elem,
"ext-link",
attrib={"ext-link-type": ext_link_type, "xlink:href": xlink_href},
).text = ext_link_text
ext_link_text = ext_link.get("text")
comment = ext_link.get("comment")

if ext_link_text:
ext_link_attributes = {"ext-link-type": ext_link_type, "xlink:href": xlink_href}

if comment:
comment_elem = ET.SubElement(element_citation_elem, "comment")
comment_elem.text = comment
ET.SubElement(comment_elem, "ext-link", attrib=ext_link_attributes).text = ext_link_text
else:
ET.SubElement(element_citation_elem, "ext-link", attrib=ext_link_attributes).text = ext_link_text

for pub_id in data.get("pub-ids") or []:
pub_id_type = pub_id.get("pub-id-type")
Expand Down
66 changes: 66 additions & 0 deletions tests/sps/formats/sps_xml/test_ref.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,33 @@ def test_build_ref_ext_link_text_None(self):
generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml")
self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip())

def test_build_ref_ext_link_in_comment(self):
self.maxDiff = None
data = {
"ref-id": "B1",
"publication-type": "journal",
"ext-link": [
{
"ext-link-type": "uri",
"xlink:href": "http://socialsciences.scielo.org",
"text": "http://socialsciences.scielo.org",
"comment": "Disponível em: "
}
]
}
expected_xml_str = (
'<ref id="B1">'
'<element-citation publication-type="journal">'
'<comment>'
'Disponível em: <ext-link ext-link-type="uri" xlink:href="http://socialsciences.scielo.org">http://socialsciences.scielo.org</ext-link>'
'</comment>'
'</element-citation>'
'</ref>'
)
ref_elem = build_ref(data)
generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml")
self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip())


class TestBuildRefPubId(unittest.TestCase):
def test_build_ref_pub_id(self):
Expand Down Expand Up @@ -319,3 +346,42 @@ def test_build_ref_date_in_citation_text_None(self):
ref_elem = build_ref(data)
generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml")
self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip())


class TestBuildRefPersonGroup(unittest.TestCase):
def test_build_ref_person_group(self):
data = {
"ref-id": "B1",
"publication-type": "journal",
}
node = {
"person-group": [
ET.fromstring(
'<person-group person-group-type="author">'
'<name>'
'<surname>Einstein</surname>'
'<given-names>Albert</given-names>'
'<prefix>Prof.</prefix>'
'<suffix>Neto</suffix>'
'</name>'
'</person-group>'
)
]
}
expected_xml_str = (
'<ref id="B1">'
'<element-citation publication-type="journal">'
'<person-group person-group-type="author">'
'<name>'
'<surname>Einstein</surname>'
'<given-names>Albert</given-names>'
'<prefix>Prof.</prefix>'
'<suffix>Neto</suffix>'
'</name>'
'</person-group>'
'</element-citation>'
'</ref>'
)
ref_elem = build_ref(data, node)
generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml")
self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip())