Validates mxGraph XML syntax for draw.io compatibility. Args: mxgraph_code: The mxGraph XML code to validate. Returns: Tuple of (is_valid, error_message_or_success_message)
(mxgraph_code: str)
| 952 | |
| 953 | |
| 954 | def validate_mxgraphxml_syntax(mxgraph_code: str) -> Tuple[bool, str]: |
| 955 | """ |
| 956 | Validates mxGraph XML syntax for draw.io compatibility. |
| 957 | |
| 958 | Args: |
| 959 | mxgraph_code: The mxGraph XML code to validate. |
| 960 | |
| 961 | Returns: |
| 962 | Tuple of (is_valid, error_message_or_success_message) |
| 963 | """ |
| 964 | try: |
| 965 | import xml.etree.ElementTree as ET |
| 966 | |
| 967 | code = mxgraph_code.strip() |
| 968 | |
| 969 | # Check for mxfile wrapper |
| 970 | if not code.startswith('<mxfile'): |
| 971 | return False, "mxGraph XML must start with <mxfile>" |
| 972 | |
| 973 | if not code.endswith('</mxfile>'): |
| 974 | return False, "mxGraph XML must end with </mxfile>" |
| 975 | |
| 976 | # Try to parse as XML |
| 977 | try: |
| 978 | root = ET.fromstring(code) |
| 979 | except ET.ParseError as e: |
| 980 | return False, f"XML parsing error: {e}" |
| 981 | |
| 982 | # Check for required structure: mxfile > diagram > mxGraphModel > root |
| 983 | diagram = root.find('.//diagram') |
| 984 | if diagram is None: |
| 985 | return False, "Missing <diagram> element inside <mxfile>" |
| 986 | |
| 987 | graph_model = diagram.find('.//mxGraphModel') |
| 988 | if graph_model is None: |
| 989 | return False, "Missing <mxGraphModel> element inside <diagram>" |
| 990 | |
| 991 | root_elem = graph_model.find('.//root') |
| 992 | if root_elem is None: |
| 993 | return False, "Missing <root> element inside <mxGraphModel>" |
| 994 | |
| 995 | # Check for base mxCells (id="0" and id="1") |
| 996 | mxcells = root_elem.findall('mxCell') |
| 997 | cell_ids = [cell.get('id') for cell in mxcells] |
| 998 | |
| 999 | if '0' not in cell_ids: |
| 1000 | return False, "Missing required mxCell with id='0'" |
| 1001 | |
| 1002 | if '1' not in cell_ids: |
| 1003 | return False, "Missing required mxCell with id='1' (default parent)" |
| 1004 | |
| 1005 | # Check that all mxCells (except id="0") have parent attribute |
| 1006 | for cell in mxcells: |
| 1007 | cell_id = cell.get('id') |
| 1008 | if cell_id != '0' and cell.get('parent') is None: |
| 1009 | return False, f"mxCell id='{cell_id}' is missing required 'parent' attribute" |
| 1010 | |
| 1011 | # Check for unquoted attributes in XML tags |
no outgoing calls
no test coverage detected