Как создать SVG из XML-данных (для использования в Exist-DB)

У меня есть XML-файл, как:

<SWIAT>
<KRAINA_GEOG TYP="Pobrzeze">
    <NAZWA>Południowobałtyckie</NAZWA>
    <POWIERZCHNIA>19000</POWIERZCHNIA>
    <OPADY_MIN>400</OPADY_MIN>
    <OPADY_MAX>800</OPADY_MAX>
</KRAINA_GEOG>
<KRAINA_GEOG TYP="Nizina">
    <NAZWA>Środkowoeuropejska</NAZWA>
    <POWIERZCHNIA>540000</POWIERZCHNIA>
    <OPADY_MIN>400</OPADY_MIN>
    <OPADY_MAX>750</OPADY_MAX>
    <KRAINA_GEOG TYP="Nizina">
        <NAZWA>Holenderska</NAZWA>
        <POWIERZCHNIA>24915</POWIERZCHNIA>
        <OPADY_MIN>550</OPADY_MIN>
        <OPADY_MAX>700</OPADY_MAX>
    </KRAINA_GEOG>
    <KRAINA_GEOG TYP="Nizina">
        <NAZWA>Południowowielkopolska</NAZWA>
        <POWIERZCHNIA>17000</POWIERZCHNIA>
        <OPADY_MIN>500</OPADY_MIN>
        <OPADY_MAX>650</OPADY_MAX>
        <KRAINA_GEOG TYP="Kotlina">
            <NAZWA>Szczercowska</NAZWA>
            <POWIERZCHNIA>1203</POWIERZCHNIA>
            <OPADY_MIN>500</OPADY_MIN>
            <OPADY_MAX>600</OPADY_MAX>
        </KRAINA_GEOG>
        <KRAINA_GEOG TYP="Rownina">
            <NAZWA>Rychwalska</NAZWA>
            <POWIERZCHNIA>1186</POWIERZCHNIA>
        </KRAINA_GEOG>
    </KRAINA_GEOG>
</KRAINA_GEOG>

И я хочу сделать гистограмму SVG со значениями от <POWIERZCHNIA>, Как это сделать? Я хочу использовать его в Exist- db. Есть идеи? Спасибо за помощь.

1 ответ

Решение

Вы можете сгенерировать SVG с помощью XSLT, хотя вы можете найти библиотеку диаграмм, которая может не требовать изучения XSLT. С XSLT вы выбираете узлы, которые вы хотите использовать с помощью XPath, и можете манипулировать ими любым удобным для вас способом. Вы даже можете генерировать его динамически на лету в браузерах (хотя есть ограничения по версии).

Я написал учебник по генерации SVG-диаграмм с использованием XSLT 1.0. К сожалению, это на португальском языке, и у меня никогда не было времени, чтобы перевести его. Но я адаптировал ваш исходный XML и написал небольшую таблицу стилей XSLT, которая сгенерирует простую гистограмму SVG с цифрами во всех POWIERZCHNIA поле (не считая вложенности).

Я определил некоторые переменные с фиксированными значениями для измерений. $max-powierzchnia Переменная выбирает наибольшее значение, которое будет использоваться для расчета длины бара, используя значение в POWIERZCHNIA * $max-bar-length / $max-powierzchnia, SWIAT Шаблон XSL определяет корневые элементы SVG, затем сортирует по (в порядке убывания POWIERZCHNIA) и обрабатывает все KRAINA_GEOG узлы, которые преобразуются в KRAINA_GEOG шаблон.

Это таблица стилей:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    version="1.0">

    <xsl:output indent="yes"/>

    <xsl:variable name="svg-width" select="1200" />
    <xsl:variable name="svg-height" select="900" />
    <xsl:variable name="max-bar-length" select="$svg-width - 400" />

    <xsl:variable name="bar-height" select="20" />
    <xsl:variable name="bar-spacing" select="10" />
    <xsl:variable name="bar-start" select="200" />

    <xsl:variable name="max-powierzchnia" select="//POWIERZCHNIA[not(. &lt; //POWIERZCHNIA)]" />

    <xsl:template match="SWIAT">
        <svg viewBox="0 0 {$svg-width} {$svg-height}" width="{$svg-width}px" height="{$svg-height}px">
            <g id="bar-chart" font-size="16" transform="translate(20,100)">
                <xsl:apply-templates select="//KRAINA_GEOG">
                    <xsl:sort order="descending" select="POWIERZCHNIA" />
                </xsl:apply-templates>
            </g>
        </svg>
    </xsl:template>

    <xsl:template match="KRAINA_GEOG">
        <xsl:variable name="bar-width" select="POWIERZCHNIA * $max-bar-length div $max-powierzchnia" />
        <g id="bar_{position()}" 
            transform="translate(0, {(position() - 1) * ($bar-height + $bar-spacing)})">
            <text x="0" y="{($bar-height + $bar-spacing) div 2}"><xsl:number format="1. " value="position()"/>
                <xsl:value-of select="NAZWA"/></text>
            <rect x="{$bar-start}" y="0" width="{$bar-width}" height="{$bar-height}" fill="lightgray"/>
            <text x="{$bar-width + $bar-start + 5}" y="{($bar-height + $bar-spacing) div 2}"><xsl:value-of select="POWIERZCHNIA"/></text>
        </g>
    </xsl:template>

</xsl:stylesheet>

И вот результирующий SVG, который вы получаете при запуске исходного XML + этой таблицы стилей XSL через процессор XSLT: http://codepen.io/helderdarocha/pen/iJrFb

Вы также можете попробовать сгенерировать его на лету, сохранив приведенную выше таблицу стилей XSLT в файл (svg-graph.xsl), добавив <?xml-stylesheet инструкция по обработке в ваш XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="svg-graph.xsl"?>
<SWIAT>
    <KRAINA_GEOG TYP="Pobrzeze">
        <NAZWA>Południowobałtyckie</NAZWA>
        <POWIERZCHNIA>19000</POWIERZCHNIA>
...

И загрузив его в браузер, такой как FireFox.

Другие вопросы по тегам