Разбор нескольких строк с использованием XSLT - PullRequest
2 голосов
/ 18 мая 2011

У меня есть следующий узел, который мне нужно проанализировать с помощью XSLT 1.0 из XML-файла

<log>Passed -ID:1 -Log:
Passed -ID:2 -Log:Suite
File/Folder
Failed -ID:3 -Log:Suite
Validate Install Failed
Passed -ID:4 -Log:
</log>

Вот -ID: -Log:

, как вы можете видеть, может быть написано в одну строку или в несколько строк.

В результате я хотел бы получить еще один XML-файл, в котором будут проанализированы данные с узла. Если прошла запись с ID, то мне нужно написать "/>. Если запись не удалась, мне нужно написать

<testcase name="<ID Name>">
  <failure message="<Log Message>"/>
</testcase>

Другими словами, мне нужно получить этот XML-файл.

<xml>
   <testcase name="1"/>
   <testcase name="2"/>
   <testcase name="3">
      <failure message="Suite Validate Install Failed"/>
   </testcase>
   <testcase name="4"/>
</xml>

Как вы думаете, что может быть лучшим способом сделать это?

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

Спасибо.

Ответы [ 2 ]

2 голосов
/ 18 мая 2011

XSLT не подходит для этой задачи.XSLT отлично подходит для преобразования структуры XML-документов (обычно в другой XML-документ, но возможен также XML-текст).XSLT не подходит для анализа текста и манипулирования им.

У вас есть какой-то структурированный текст, который оказывается внутри элемента XML.

Я бы выбрал другой метод преобразования, Regex, илипростые методы анализа строк.

0 голосов
/ 20 мая 2011

В следующем XSLT показано, как разделить содержимое log в токенах, используя tokenize(). Возможно, есть лучший выбор с XSLT 2.0 (например, xsl:analyze-string), но из-за использования только tokenize() это решение применимо также к XSLT 1.0 , расширенному с EXSLT шаблоны.


XSLT 2.0 протестировано на Saxon-B 9.0.0.2J

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>


    <xsl:template match="/">
        <xml>
            <xsl:variable name="string" select="."/>

            <xsl:variable name="pass" select="tokenize($string,'Passed -ID:')[not(position()=1)]"/>

            <xsl:for-each select="$pass">

                <xsl:choose>
                    <xsl:when test="contains(.,'Failed -ID:')">
                        <xsl:variable name="failure" select="tokenize(.,'Failed -ID:')"/>

                        <xsl:for-each select="$failure">
                            <xsl:choose>
                                <xsl:when   test="position()=1">
                                    <testcase name="{tokenize(.,'\s-Log:')[1]}"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:variable name="tc" select="tokenize(.,'\s-Log:')"/>
                                    <testcase name="{$tc[1]}">
                                        <failure message="{$tc[2]}"/>
                                    </testcase>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:for-each>
                    </xsl:when>

                    <xsl:otherwise>
                        <testcase name="{tokenize(.,'\s-Log:')[1]}"/>
                    </xsl:otherwise>

                </xsl:choose>
            </xsl:for-each>
            <xsl:apply-templates/>
        </xml>
    </xsl:template>

    <xsl:template match="log"/>


</xsl:stylesheet>

Вышеуказанный XSLT применяется к следующему входу:

<log>Passed -ID:1 -Log:
Passed -ID:2 -Log:Suite
File/Folder
Failed -ID:3 -Log:Suite
Validate Install Failed
Passed -ID:4 -Log:
Failed -ID:5 -Log:aaaaaa
Failed -ID:6 -Log:dfsfsdf
Failed -ID:7 -Log:dsfsfs
fsdfsdfsdfsdfs
Passed -ID:8 -Log:dfsdfsf
Failed -ID:9 -Log:dfsdfs
</log>

Создает следующий вывод:

<xml>
   <testcase name="1"/>
   <testcase name="2"/>
   <testcase name="3">
      <failure message="Suite&#xA;Validate Install Failed&#xA;"/>
   </testcase>
   <testcase name="4"/>
   <testcase name="5">
      <failure message="aaaaaa&#xA;"/>
   </testcase>
   <testcase name="6">
      <failure message="dfsfsdf&#xA;"/>
   </testcase>
   <testcase name="7">
      <failure message="dsfsfs&#xA;fsdfsdfsdfsdfs&#xA;"/>
   </testcase>
   <testcase name="8"/>
   <testcase name="9">
      <failure message="dfsdfs&#xA;"/>
   </testcase>
</xml>

Обратите внимание, что &#xA; происходит из-за перевода строки исходного текста, потому что мы помещаем содержимое в значение атрибута. Чтобы избавиться от этого, было бы лучше включить сообщение в качестве содержимого элемента failure. В любом случае следующая статья имеет дело с хитрыми пробелами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...