Ответы пользователя по тегу XML
  • XML. Как описать XSL, который будет вычислять факториал числа?

    @Roman-Fov
    Рекурсия???...
    Ответ написан
    Комментировать
  • XML. Как сделать выборку с помощью XPath?

    @Roman-Fov
    Один момент.
    <office code="ВТ">
    <lesson no="2" complex="BT">


    символы в office/@code и lesson/@complex не совпадают. Кириллица или чёт ещё там в одном из них. Это надо исправить.

    index.xml
    <?xml-stylesheet type='text/xsl' href='/time.xsl'?>
    <timeTable>
      <offices>
        <office code="КУ">
            <name>Курская</name>
            <address>Костомаровский пер., дом 3, стр 4, Москва, 105120</address>
        </office>
        <office code="BT">
            <name>ВДНХ Техноград</name>
            <address>пр-т Мира, 119 строение 63, Москва, 129223</address>
        </office>
      </offices>
      <lessons>
        <lesson no="1" complex="КУ">
          <thema>Обзор XML технологий</thema>
          <date>2021-01-19</date>
          <time>10:00</time>
        </lesson>
        <lesson no="2" complex="BT">
          <thema>Введение в XML</thema>
          <date>2021-01-23</date>
          <time>17:20</time>
        </lesson>
        <lesson no="3" complex="BT">
          <thema>Правила XML</thema>
          <date>2021-01-26</date>
          <time>15:30</time>
        </lesson>
        <lesson no="4" complex="КУ">
          <thema>Пространства имён XML</thema>
          <date>2021-01-29</date>
          <time>10:00</time>
        </lesson>
        <lesson no="5" complex="BT">
          <thema>DTD: Описание структуры документа</thema>
          <date>2021-02-03</date>
          <time>17:20</time>
        </lesson>
        <lesson no="6" complex="BT">
          <thema>DTD: определение сущностей</thema>
          <date>2021-02-08</date>
          <time>15:30</time>
        </lesson>
        <lesson no="7" complex="КУ">
          <thema>Введение в XML Схемы</thema>
          <date>2021-02-12</date>
          <time>10:00</time>
        </lesson>
        <lesson no="8" complex="BT">
          <thema>XML Схема: типы данных</thema>
          <date>2021-02-17</date>
          <time>17:20</time>
        </lesson>
        <lesson no="9" complex="BT">
          <thema>Атрибуты типов</thema>
          <date>2021-02-21</date>
          <time>15:30</time>
        </lesson>
        <lesson no="10" complex="КУ">
          <thema>XML Схема: Расширение сложных типов</thema>
          <date>2021-02-25</date>
          <time>10:00</time>
        </lesson>
      </lessons>
    </timeTable>


    time.xsl
    <xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <xsl:apply-templates select="timeTable"/>
        </xsl:template>
    
        <xsl:template match="timeTable">
            <html>
                <head>
                    <title>page</title>
                </head>
                <body>
                    <xsl:apply-templates select="offices"/>
                </body>
            </html>
        </xsl:template>
    
        <xsl:template match="offices">
            <div>
                <xsl:apply-templates select="office"/>
            </div>
        </xsl:template>
    
        <xsl:template match="office">
            <xsl:variable name="office_code" select="@code"/>
            <div>
                <xsl:text>Комплекс </xsl:text>
                <xsl:value-of select="name"/>
                <xsl:text>: всего занятий </xsl:text>
                <xsl:value-of select="count(/timeTable/lessons/lesson[@complex = $office_code])"/>
                <xsl:text>, занятий в 10:00 </xsl:text>
                <xsl:value-of select="count(/timeTable/lessons/lesson[@complex = $office_code and time = '10:00'])"/>
            </div>
        </xsl:template>
    </xsl:stylesheet>


    Result:
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <title>page</title>
        </head>
        <body>
            <div>
                <div>Комплекс Курская: всего занятий 4, занятий в 10:00 4</div>
                <div>Комплекс ВДНХ Техноград: всего занятий 6, занятий в 10:00 0</div>
            </div>
        </body>
    </html>


    Поднимаем любой сервер (если на локалке) и открываем index.xml
    Ответ написан
    Комментировать
  • Как пользоваться оператором AND для XPATH?

    @Roman-Fov
    Запрос отрабатывает. Может не то хотим выбрать?
    Какой результат ожидается?
    Ответ написан
    3 комментария
  • XPath и даты, можно ли делать условные запросы?

    @Roman-Fov
    Да. Делать запросы, включая довольно сложные к xml можно.
    Да. И с числами всё будет ок. И со строками тоже.
    Ну... и с датами тоже. Нам будет сложно, но мы справимся.

    Но зачем?
    XML не создавался как решение проблемы с хранением данных.
    Он для этого не предназначен.
    А базы данных предназначены для хранения данных.

    Записи вида "дата + пара чисел + комментарий" действительно смотрятся в нём органично, ровно как записи любого другого вида и структуры.
    Но более органично представятся записи такого вида в таблице бд.

    При всех своих недостатках перед базами, xml не предоставляет никаких преимуществ пред ними.
    Ответ написан
    Комментировать
  • Парсинг сайтов xpath?

    @Roman-Fov
    Сам Xpath не такая обширная тема. Если и есть книга только по нему, то она не более 50 страниц. Там под пол сотни функций и с десяток осей.

    Если быстро разобраться, то mdn наше всё.
    Если просто почитать, то любая книга зарубежного издательства в названии или описании которой будет XML. Там обязательно будет глава про Xpath.
    Ответ написан
    Комментировать
  • Как исключить div с display none?

    @Roman-Fov
    там проблема у вас в самом начале запроса
    А именно задесь:
    //div[not(contains(@style, 'none'))]

    Этим хотели отсечь скрытые .bx_slider_conteiner, но по факту выбирает не их, а .bx_slide
    Отсюда и вся эта песня
    Ответ написан
  • Как трансформировать XML с помощью XQuery?

    @Roman-Fov
    Так всё просто. Нужно выбрать элементы содержащие в себе определённый год. Сделать это можно так (для 2018):
    /ScheduleTable/Schedule[Year = '2018']/Item
    Для других год только менять и писать куда надо
    Ответ написан
    Комментировать
  • Как проверить существует ли участок дерева в XML?

    @Roman-Fov
    Так посчитать их же
    XML
    <root>
    	<foo>
    		<bar>
    			<baz>asdf</baz>
    			<text>text1</text>
    		</bar>
    	</foo>
    	<foo>
    		<bar>
    			<text>text2</text>
    		</bar>
    	</foo>
    	<foo>
    		<bar>
    			<baz>3</baz>
    			<text>text3</text>
    		</bar>
    	</foo>
    </root>


    XSLt
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="/root">
        <xsl:apply-templates select="foo"/>
      </xsl:template>
    
      <xsl:template match="foo">
        <h1 style="color:red;">
          <xsl:attribute name="style">
            <xsl:choose>
              <xsl:when test="count(bar/baz) &gt; 0">
                <xsl:text>color: red;</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                <xsl:text>color: green;</xsl:text>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:attribute>
          <xsl:apply-templates select="bar/text"/>
        </h1>
      </xsl:template>
    </xsl:stylesheet>


    Result
    <h1 style="color: red;">text1</h1>
    <h1 style="color: green;">text2</h1>
    <h1 style="color: red;">text3</h1>
    Ответ написан
    Комментировать
  • Почему в Google Chrome и в Opera не открывается xml-файл с подключённым к нему xsl-стилями?

    @Roman-Fov
    Всё он работает. Только нужно предварительно закрыть все другие окна хрома. Если он работает в фоне, то убить все его процессы. Только тогда запускать его с флагом --allow-file-access-from-files.
    Работает во всех браузерах основанных на Chromium.
    Или создать сервер (денвер или что там сейчас на винде) и обращаться к файлам через http. Тогда этой ошибки возникать не будет вообще без флагов всяких.
    Ответ написан
    3 комментария
  • Как делать xslt-преобразование для длинных xml-файлов?

    @Roman-Fov
    Если отличается структурой элемент, то придётся обрабатывать отдельно.
    Если есть общие черты, то можно вместе. Перечисляйте их в apply-templates select и template match.

    XML
    https://pastebin.com/DeN4rRnY

    XSLt
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:template match="/root/APPLICATION">
        <html>
        <body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">
        <h1><xsl:value-of select="root/APPLICATION/@NAME"/> </h1>
          <table border="1">
            <tr>
              <td>ID</td>
              <td>Deleted</td>
              <td>IsLocked</td>
              <td>RetriveTime</td>
              <td>ChangeTime</td>
              <td>AccessTime</td>
              <td>SecureStyleID</td>
              <td>Name</td>
              <td>DBName</td>
              <td>TheComment</td>
            </tr>
            <xsl:apply-templates select="MTZAPP_COL/MTZAPP | OBJECTMODE_COL/OBJECTMODE"/>
          </table>
      </body>
      </html>
      </xsl:template>
    
      <xsl:template match="MTZAPP_COL/MTZAPP | OBJECTMODE_COL/OBJECTMODE">
        <tr>
          <td><xsl:value-of select="@ID"/></td>
          <td><xsl:value-of select="@Deleted"/></td>
          <td><xsl:value-of select="@IsLocked"/></td>
          <td><xsl:value-of select="@RetriveTime"/></td>
          <td><xsl:value-of select="@ChangeTime"/></td>
          <td><xsl:value-of select="@AccessTime"/></td>
          <td><xsl:value-of select="@SecureStyleID"/></td>
          <td><xsl:value-of select="@Name"/></td>
          <td><xsl:value-of select="@DBName"/></td>
          <td><xsl:value-of select="@TheComment"/></td>
        </tr>
      </xsl:template>
    </xsl:stylesheet>


    Result
    https://pastebin.com/PizDCL0M

    PS циклы в XSLt не есть хорошо. Те я хочу сказать, что нужно избегать циклов в пользу apply templates везде, где это возможно. Они усложняют таблицы, делают невозможным повторное использование и вообще противоречит идеологии инструмента
    Ответ написан
    Комментировать
  • В чем плюсы и минусы разбора XML через xpath?

    @Roman-Fov
    Сложно судить о плюсах и минусах если нет альтернатив. Всё что есть, так или иначе использует xpath. Стандарт для разбора xml.

    Если нужны именно минусы, то это хреновая работа со строками и наборами узлов. И вложенные запросы хочется тоже. Но если посмотреть как устроены запросы к документу в css, то становится понятно, что зажрался совсем и всё тут хорошо на самом деле)
    Ответ написан
    Комментировать
  • Как динамически добавлять блоки или изменять значения полей при использовании xslt?

    @Roman-Fov
    Раз для теста, то можно однотипные данные писать

    data.xml
    <?xml version="1.0"?>
    <root>
    <foo/>
    </root>


    proc.xsl с рекурсией
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="xml" indent="yes"/>
    
        <xsl:template match="/">
            <operations>
                <xsl:call-template name="operation">
                    <xsl:with-param name="counter" select="5"/>
                </xsl:call-template>
            </operations>
        </xsl:template>
    
        <xsl:template name="operation">
            <xsl:param name="counter" select="1"/>
    
            <operation>
                <name>
                    <xsl:text>Ivan</xsl:text>
                    <xsl:value-of select="$counter"/>
                </name>
                <price>
                    <xsl:value-of select="100 * $counter"/>
                </price>
            </operation>
    
            <xsl:if test="$counter > 0">
                <xsl:call-template name="operation">
                    <xsl:with-param name="counter" select="$counter - 1"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:template>
    </xsl:stylesheet>


    xsltproc proc.xsl data.xml > result.xml
    cat result.xml


    <?xml version="1.0"?>
    <operations>
      <operation>
        <name>Ivan5</name>
        <price>500</price>
      </operation>
      <operation>
        <name>Ivan4</name>
        <price>400</price>
      </operation>
      <operation>
        <name>Ivan3</name>
        <price>300</price>
      </operation>
      <operation>
        <name>Ivan2</name>
        <price>200</price>
      </operation>
      <operation>
        <name>Ivan1</name>
        <price>100</price>
      </operation>
      <operation>
        <name>Ivan0</name>
        <price>0</price>
      </operation>
    </operations>


    или для второй версии на циклах
    proc.xsl
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes"/>
    
        <xsl:template match="/">
            <operations>
                <xsl:for-each select="1 to 10">
                    <operation>
                        <name>
                            <xsl:text>Ivan</xsl:text>
                            <xsl:value-of select="position()"/>
                        </name>
                        <price>
                            <xsl:value-of select="100 * position()"/>
                        </price>
                    </operation>
                </xsl:for-each>
            </operations>
        </xsl:template>
    </xsl:stylesheet>


    saxonb-xslt -s:data.xml -xsl:proc.xsl -o:result.xml
    cat result.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <operations>
       <operation>
          <name>Ivan1</name>
          <price>100</price>
       </operation>
       <operation>
          <name>Ivan2</name>
          <price>200</price>
       </operation>
       <operation>
          <name>Ivan3</name>
          <price>300</price>
       </operation>
       <operation>
          <name>Ivan4</name>
          <price>400</price>
       </operation>
       <operation>
          <name>Ivan5</name>
          <price>500</price>
       </operation>
       <operation>
          <name>Ivan6</name>
          <price>600</price>
       </operation>
       <operation>
          <name>Ivan7</name>
          <price>700</price>
       </operation>
       <operation>
          <name>Ivan8</name>
          <price>800</price>
       </operation>
       <operation>
          <name>Ivan9</name>
          <price>900</price>
       </operation>
       <operation>
          <name>Ivan10</name>
          <price>1000</price>
       </operation>
    </operations


    Это оно? Так хотели генерировать их?
    Ответ написан
    1 комментарий
  • Как правильно составить XSL шаблон?

    @Roman-Fov
    Вопрос, как мне правильно составить XSL шаблон чтобы я мог пробежаться по всем вложенным группам?


    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output indent="yes" encoding="utf-8" version="1.0"/>
    
    	<xsl:template match="/informationsystem">
    		<xsl:if test="count(informationsystem_group) &gt; 0">
    			<ul>
    				<xsl:apply-templates select="//informationsystem_group"/>
    			</ul>
    		</xsl:if>
    	</xsl:template>
    
    	<xsl:template match="informationsystem_group">
    		<li>
    			<xsl:value-of select="name"/>
    		</li>
    	</xsl:template>
    </xsl:stylesheet>
    Ответ написан
    Комментировать
  • Как разбить строку на символы?

    @Roman-Fov
    Если делать просто, то можно запользовать exslt

    XML:
    <ФИО Фамилия="Алексеев" Имя="Алексей" Отчество="Алексеевич"></ФИО>


    XSLt:
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    				xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
    
    	<xsl:template match="/">
    		<xsl:apply-templates select="ФИО/@Имя"/>
    	</xsl:template>
    
    	<xsl:template match="ФИО/@Имя">
    		<tr>
    			<xsl:for-each select="str:tokenize(string(.), '')">
    				<td>
    					<xsl:value-of select="." />
    				</td>
    			</xsl:for-each>
    		</tr>
    	</xsl:template>
    </xsl:stylesheet>


    Result:
    <tr><td>А</td><td>л</td><td>е</td><td>к</td><td>с</td><td>е</td><td>й</td></tr>
    Ответ написан
  • XSL трансформация -> CSV -> как заменить знак новой строки?

    @Roman-Fov
    Без регулярок примерно так:
    <documentRecipientAddressData>
          <street>Centroallee 1000
    Einfahrt Parkhaus 7 an der "Alten Waltz" gegenüber Tryp Hotel ...</street>
          <street>Centroallee
    1000
    Einfahrt
    Parkhaus 7 an der
    "Alten Waltz" gegenüber Tryp Hotel ...</street>
          <street>Centroallee 1000 Einfahrt Parkhaus 7 an der "Alten Waltz" gegenüber Tryp Hotel ...</street>
    </documentRecipientAddressData>


    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    	<xsl:template match="/documentRecipientAddressData/street">
    		<xsl:variable name="street">
    			<xsl:call-template name="replace-line-breaks">
    				<xsl:with-param name="text">
    					<xsl:call-template name="normalize-line-breaks">
    						<xsl:with-param name="text" select="."/>
    					</xsl:call-template>
    				</xsl:with-param>
    			</xsl:call-template>
    		</xsl:variable>
    		<xsl:value-of select="normalize-space($street)"/>
    		<xsl:text>&#xa;</xsl:text>
    		<xsl:variable name="street">
    			<xsl:call-template name="normalize-line-breaks">
    				<xsl:with-param name="text" select="."/>
    			</xsl:call-template>
    		</xsl:variable>
    		<xsl:value-of select="replace($street, '\n', ', ')"/>
    		<xsl:text>&#xa;&#xa;</xsl:text>
    	</xsl:template>
    
    	<xsl:template name="replace-line-breaks">
    		<xsl:param name="text"/>
    
    		<xsl:choose>
    			<xsl:when test="not(contains($text, '&#xa;'))">
    				<xsl:value-of select="$text"/>
    			</xsl:when>
    			<xsl:otherwise>
    				<xsl:value-of select="substring-before($text, '&#xa;')"/>
    				<xsl:text>,&#160;</xsl:text>
    				<xsl:call-template name="replace-line-breaks">
    					<xsl:with-param name="text" select="substring-after($text, '&#xa;')"/>
    				</xsl:call-template>
    			</xsl:otherwise>
    		</xsl:choose>
    	</xsl:template>
    
    	<xsl:template name="normalize-line-breaks">
    		<xsl:param name="text"/>
    
    		<xsl:choose>
    			<xsl:when test="not(contains($text, '&#xa;&#xa;'))">
    				<xsl:value-of select="$text"/>
    			</xsl:when>
    			<xsl:otherwise>
    				<xsl:variable name="text">
    					<xsl:value-of select="substring-before($text, '&#xa;&#xa;')"/>
    					<xsl:text>&#xa;</xsl:text>
    					<xsl:value-of select="substring-after($text, '&#xa;&#xa;')"/>
    				</xsl:variable>
    				<xsl:call-template name="normalize-line-breaks">
    					<xsl:with-param name="text" select="$text"/>
    				</xsl:call-template>
    			</xsl:otherwise>
    		</xsl:choose>
    	</xsl:template>
    </xsl:stylesheet>


    Centroallee 1000, Einfahrt Parkhaus 7 an der "Alten Waltz" gegenüber Tryp Hotel ...
    Centroallee 1000, Einfahrt Parkhaus 7 an der "Alten Waltz" gegenüber Tryp Hotel ...
    
    Centroallee, 1000, Einfahrt, Parkhaus 7 an der, "Alten Waltz" gegenüber Tryp Hotel ...
    Centroallee, 1000, Einfahrt, Parkhaus 7 an der, "Alten Waltz" gegenüber Tryp Hotel ...
    
    Centroallee 1000 Einfahrt Parkhaus 7 an der "Alten Waltz" gegenüber Tryp Hotel ...
    Centroallee 1000 Einfahrt Parkhaus 7 an der "Alten Waltz" gegenüber Tryp Hotel ...

    Какт так
    В Ваш шаблон уж сами приспособите

    PS: {username}, может есть лучший способ? Буду рад выслушать неравнодушных
    Ответ написан
    Комментировать
  • Как получить элемент с классом по шаблону/маски (xpath)?

    @Roman-Fov
    <root>
    	<div class="class1-s">a</div>
    	<div class="class1_a">b</div>
    	<div class="  class1+g 	">b</div>
    	<div class="class1-s1">c</div>
    	<div class="class1-s134">c</div>
    	<div class="cls1-s134">c</div>
    	<div class="class1-s134">c</div>
    	<div c="zclass1-s1">c</div>
    	<div>c</div>
    </root>


    Есть вариант. Выбираем сначала по starts-with и потом считаем количество символов:
    /root/div[starts-with(normalize-space(@class), 'class1') and string-length(normalize-space(@class)) = string-length('class1') + 2]


    Или если очень хочется регулярок, то:
    /root/div[matches(normalize-space(@class), '^class1..$')]
    Ответ написан
    Комментировать
  • Как преобразовать лог из XML с помощью XSLT?

    @Roman-Fov
    Насколько я знаю, в xml может быть только один корневой элемент.

    Неправильное, но рабочее решение:
    Обернуть все корневые элементы в один новый корневой элемент в блокноте++ вручную и обработать как надо.

    Хорошее решение:
    Генерировать хороший xml
    Ответ написан
    Комментировать
  • Как выбрать по два элемента в XSLT?

    @Roman-Fov
    Можно так

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:template match="/items">
    		<ul>
    			<xsl:apply-templates select="item[position() mod 2 = 1]" />
    		</ul>
    	</xsl:template>
    
    	<xsl:template match="item">
    		<li>
    			<img src="{@src}"/>
    			<img src="{following::item/@src}"/>
    		</li>
    	</xsl:template>
    </xsl:stylesheet>


    Выдаст
    <ul>
       <li>
          <img src="/1.jpg"/>
          <img src="/2.jpg"/>
       </li>
       <li>
          <img src="/3.jpg"/>
          <img src="/4.jpg"/>
       </li>
       <li>
          <img src="/5.jpg"/>
          <img src=""/>
       </li>
    </ul>
    Ответ написан
    1 комментарий
  • Как распарсить xml?

    @Roman-Fov
    /ns2:purchaseNotice/ns2:body/ns2:item/*[local-name()='guid']/text()
    Ответ написан