MCPcopy Create free account
hub / github.com/ResearAI/AutoFigure / validateMxCellStructure

Function validateMxCellStructure

frontend/lib/utils.ts:541–671  ·  view source on GitHub ↗
(xml: string)

Source from the content-addressed store, hash-verified

539 * @returns null if valid, error message string if invalid
540 */
541export function validateMxCellStructure(xml: string): string | null {
542 const parser = new DOMParser()
543 const doc = parser.parseFromString(xml, "text/xml")
544
545 // Check for XML parsing errors (includes unescaped special characters)
546 const parseError = doc.querySelector("parsererror")
547 if (parseError) {
548 return `Invalid XML: The XML contains syntax errors (likely unescaped special characters like <, >, & in attribute values). Please escape special characters: use &lt; for <, &gt; for >, &amp; for &, &quot; for ". Regenerate the diagram with properly escaped values.`
549 }
550
551 // Get all mxCell elements once for all validations
552 const allCells = doc.querySelectorAll("mxCell")
553
554 // Single pass: collect IDs, check for duplicates, nesting, orphans, and invalid parents
555 const cellIds = new Set<string>()
556 const duplicateIds: string[] = []
557 const nestedCells: string[] = []
558 const orphanCells: string[] = []
559 const invalidParents: { id: string; parent: string }[] = []
560 const edgesToValidate: {
561 id: string
562 source: string | null
563 target: string | null
564 }[] = []
565
566 allCells.forEach((cell) => {
567 const id = cell.getAttribute("id")
568 const parent = cell.getAttribute("parent")
569 const isEdge = cell.getAttribute("edge") === "1"
570
571 // Check for duplicate IDs
572 if (id) {
573 if (cellIds.has(id)) {
574 duplicateIds.push(id)
575 } else {
576 cellIds.add(id)
577 }
578 }
579
580 // Check for nested mxCell (parent element is also mxCell)
581 if (cell.parentElement?.tagName === "mxCell") {
582 nestedCells.push(id || "unknown")
583 }
584
585 // Check parent attribute (skip root cell id="0")
586 if (id !== "0") {
587 if (!parent) {
588 if (id) orphanCells.push(id)
589 } else {
590 // Store for later validation (after all IDs collected)
591 invalidParents.push({ id: id || "unknown", parent })
592 }
593 }
594
595 // Collect edges for connection validation
596 if (isEdge) {
597 edgesToValidate.push({
598 id: id || "unknown",

Callers 2

ChatMessageDisplayFunction · 0.90
loadDiagramFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected