11"""Allows output of HedSchema objects as .xml format"""
22
33from xml .etree .ElementTree import Element , SubElement
4- from hed .schema .hed_schema_constants import HedSectionKey
4+ import pandas as pd
5+ from hed .schema .hed_schema_constants import HedSectionKey , HedKey
56from hed .schema .schema_io import xml_constants , df_constants as df_constants
67from hed .schema .schema_io .schema2base import Schema2Base
78
@@ -44,8 +45,19 @@ def _output_extras(self, hed_schema):
4445
4546 def _output_sources (self , hed_schema ):
4647 sources = hed_schema .get_extras (df_constants .SOURCES_KEY )
47- if sources is None :
48+ if sources is None or sources . empty :
4849 return
50+
51+ # Filter for unmerged library schemas - only output library entries
52+ if not self ._save_merged and hed_schema .library and hed_schema .with_standard :
53+ if df_constants .in_library in sources .columns :
54+ sources = sources [sources [df_constants .in_library ].notna ()].copy ()
55+ if sources .empty :
56+ return
57+ else :
58+ # No in_library tracking, skip output for safety
59+ return
60+
4961 sources_node = SubElement (self .hed_node , xml_constants .SCHEMA_SOURCE_SECTION_ELEMENT )
5062 for _ , row in sources .iterrows ():
5163 source_node = SubElement (sources_node , xml_constants .SCHEMA_SOURCE_DEF_ELEMENT )
@@ -56,10 +68,29 @@ def _output_sources(self, hed_schema):
5668 description = SubElement (source_node , xml_constants .DESCRIPTION_ELEMENT )
5769 description .text = row [df_constants .description ]
5870
71+ # Add inLibrary attribute in merged saves if present
72+ if self ._save_merged and df_constants .in_library in row .index and pd .notna (row [df_constants .in_library ]):
73+ attribute_node = SubElement (source_node , xml_constants .ATTRIBUTE_ELEMENT )
74+ name_node = SubElement (attribute_node , xml_constants .NAME_ELEMENT )
75+ name_node .text = HedKey .InLibrary
76+ value_node = SubElement (attribute_node , xml_constants .VALUE_ELEMENT )
77+ value_node .text = row [df_constants .in_library ]
78+
5979 def _output_prefixes (self , hed_schema ):
6080 prefixes = hed_schema .get_extras (df_constants .PREFIXES_KEY )
61- if prefixes is None :
81+ if prefixes is None or prefixes . empty :
6282 return
83+
84+ # Filter for unmerged library schemas - only output library entries
85+ if not self ._save_merged and hed_schema .library and hed_schema .with_standard :
86+ if df_constants .in_library in prefixes .columns :
87+ prefixes = prefixes [prefixes [df_constants .in_library ].notna ()].copy ()
88+ if prefixes .empty :
89+ return
90+ else :
91+ # No in_library tracking, skip output for safety
92+ return
93+
6394 prefixes_node = SubElement (self .hed_node , xml_constants .SCHEMA_PREFIX_SECTION_ELEMENT )
6495 for _ , row in prefixes .iterrows ():
6596 prefix_node = SubElement (prefixes_node , xml_constants .SCHEMA_PREFIX_DEF_ELEMENT )
@@ -69,11 +100,29 @@ def _output_prefixes(self, hed_schema):
69100 prefix_namespace .text = row [df_constants .namespace ]
70101 prefix_description = SubElement (prefix_node , xml_constants .DESCRIPTION_ELEMENT )
71102 prefix_description .text = row [df_constants .description ]
103+ # Add inLibrary attribute in merged saves if present
104+ if self ._save_merged and df_constants .in_library in row .index and pd .notna (row [df_constants .in_library ]):
105+ attribute_node = SubElement (prefix_node , xml_constants .ATTRIBUTE_ELEMENT )
106+ name_node = SubElement (attribute_node , xml_constants .NAME_ELEMENT )
107+ name_node .text = HedKey .InLibrary
108+ value_node = SubElement (attribute_node , xml_constants .VALUE_ELEMENT )
109+ value_node .text = row [df_constants .in_library ]
72110
73111 def _output_external_annotations (self , hed_schema ):
74112 externals = hed_schema .get_extras (df_constants .EXTERNAL_ANNOTATION_KEY )
75- if externals is None :
113+ if externals is None or externals . empty :
76114 return
115+
116+ # Filter for unmerged library schemas - only output library entries
117+ if not self ._save_merged and hed_schema .library and hed_schema .with_standard :
118+ if df_constants .in_library in externals .columns :
119+ externals = externals [externals [df_constants .in_library ].notna ()].copy ()
120+ if externals .empty :
121+ return
122+ else :
123+ # No in_library tracking, skip output for safety
124+ return
125+
77126 externals_node = SubElement (self .hed_node , xml_constants .SCHEMA_EXTERNAL_SECTION_ELEMENT )
78127 for _ , row in externals .iterrows ():
79128 external_node = SubElement (externals_node , xml_constants .SCHEMA_EXTERNAL_DEF_ELEMENT )
@@ -86,6 +135,14 @@ def _output_external_annotations(self, hed_schema):
86135 external_description = SubElement (external_node , xml_constants .DESCRIPTION_ELEMENT )
87136 external_description .text = row [df_constants .description ]
88137
138+ # Add inLibrary attribute in merged saves if present
139+ if self ._save_merged and df_constants .in_library in row .index and pd .notna (row [df_constants .in_library ]):
140+ attribute_node = SubElement (external_node , xml_constants .ATTRIBUTE_ELEMENT )
141+ name_node = SubElement (attribute_node , xml_constants .NAME_ELEMENT )
142+ name_node .text = HedKey .InLibrary
143+ value_node = SubElement (attribute_node , xml_constants .VALUE_ELEMENT )
144+ value_node .text = row [df_constants .in_library ]
145+
89146 def _output_epilogue (self , epilogue ):
90147 if epilogue :
91148 prologue_node = SubElement (self .hed_node , xml_constants .EPILOGUE_ELEMENT )
0 commit comments