Skip to content

Rewrite SVG parser avoiding creation of intermediate XML nodes? (being more SAX2-like) #526

@tinchodias

Description

@tinchodias

In short, the XMLParser project provides tests and examples to read XML without creating a XMLnode instance for each read node. As a reference, see subclasses of SAX2ElementHandler in 'XML-Parser-Tests'.


Right now, when we want to get BlElements from a SVG string, something like this is the first step: XMLDOMParser parse: '<svg ........ </svg>'. The parser (in 'XML-Parser' package), outputs a BlElement that might be in fact a tree of elements. My question is not about the output, but about what happens in the middle to create it: The "dom" that the parser returns is "visited" by the Bloc's BlSvgFactory.

The factory will execute this method on each SVG's node:

readElementFrom: aXMLNode
	| symbol |
	aXMLNode
		splitStyleAttribute;
		inheritAttributes.

	symbol := (aXMLNode name asString , 'From:') asSymbol.

	^ (self respondsTo: symbol)
		ifTrue: [ self perform: symbol with: aXMLNode ]
		ifFalse: [ self metadataFrom: aXMLNode ]

that will send a message according to the name of the svg's element that is being read (e.g. rect, circle, path, g). That method will then read the attributes by querying each XML node like this:

positionFrom: node on: aBlElement
	| x y |
	x := y := 0.
	node
		attributeAt: 'x'
		ifPresent: [ :value | x := value asNumber ].
	node
		attributeAt: 'y'
		ifPresent: [ :value | y := value asNumber ].
	aBlElement position: x @ y

EDIT: As an example, parsing the classical tiger creates a DOM with 1200 nodes.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions