Синтаксический анализ XML: математические уравнения - пример SVG - PullRequest
2 голосов
/ 16 февраля 2020

Я хотел бы выбрать позиции и размеры шрифтов для каждого из символов, используемых в SVG математического уравнения.

Я играю с библиотекой синтаксического анализа Python XML: xml .etree.ElementTree (https://docs.python.org/3/library/xml.etree.elementtree.html).

Вот пример SVG, который я использую:

example_svg = '''<svg style="vertical-align:-10.2252022445128pt" xmlns="http://www.w3.org/2000/svg" width="193pt" height="31pt" viewBox="-1 -1 193 31">
<path d="M43.875 16.305h20.426" fill="none" stroke-width=".914" stroke="#000" stroke-miterlimit="10"></path>
<g font-family="MathFont" font-size="13.5">
<text y="11.168" x="45.874">3</text>
<text y="11.168" x="52.532">?</text> 
<text y="28.382" x="50.758">4</text>
</g>
<g font-family="MathFont" font-size="9.45">
<text y="6.327" x="60.453">3</text></g>
</svg>'''    

В латексе уравнение равно $ \ frac {3x ^ 3} {4} $.

Использование следующего кода дает мне почти все, что я хочу, но я не могу связать это с атрибутами в тексте группы. В идеале я хочу, чтобы вывод был (symbol, y_coord, x_coord, font-family, font-size).

import xml.etree.ElementTree as ET

root = ET.fromstring(example_svg)

for tag in root.findall('.//{http://www.w3.org/2000/svg}text'):
  symbol = tag.text
  y_coord = tag.get('y')
  x_coord = tag.get('x')
  print(symbol, y_coord, x_coord)

1 Ответ

1 голос
/ 17 февраля 2020

Имя и размер семейства шрифтов указаны не в элементах <text>, а в родительских группах <g>. Необходимо соблюдать осторожность, поскольку несколько <g> элементов могут казаться вложенными друг в друга.

Вы можете найти все <g> элементы с помощью find_all и временно сохранить параметры шрифта, но если вы попытаетесь это сделать чтобы сначала найти <g>, а затем <text> s, вы скоро заметите, что он не может правильно обрабатывать вложенные группы. Каждое вхождение <g> будет инициировать поиск его содержащихся элементов <text>, и поэтому, если есть набор вложенных

<g <em>group parameters</em>> <g <em>text parameters</em>> <text><em>your text</em></text> </g> </g>

, он сообщит обо всех элементах <text> дважды : один раз для каждого (вложенного или нет) <g>.

Таким образом, лучший способ - перебирать весь файл XML и сохранять информацию о шрифте как и когда Вы идете по нему.

root = ET.fromstring(example_svg)

font = None
font_size = None
for elem in root.iter():
    if elem.tag == '{http://www.w3.org/2000/svg}g':
        item = elem.get('font-family')
        if item is not None:
            font = item
        item = elem.get('font-size')
        if item is not None:
            font_size = item

    elif elem.tag == '{http://www.w3.org/2000/svg}text':
        symbol = elem.text
        y_coord = elem.get('y')
        x_coord = elem.get('x')
        print (symbol, y_coord, x_coord, font, font_size)

(Обратите внимание, что iter() требуется полное пространство имен SVG, добавленное к каждому элементу.)

Результат:

3 11.168 45.874 MathFont 13.5
? 11.168 52.532 MathFont 13.5
4 28.382 50.758 MathFont 13.5
3 6.327 60.453 MathFont 9.45
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...