XSLT 1.0 (xsltproc) - Как заменить последнее вхождение символа? - PullRequest
0 голосов
/ 17 апреля 2019

Я пытаюсь заменить последнее вхождение '.' символ с символом '/' при использовании XSLT (xslt 1.0 xsltproc). Как я могу это сделать?

Input.xml

<testng-results>
<suite>
<test>
<class name="system.apps.webdriver.tests.crm.mot.CreateTerritoryProposalTest">
<test-method status="PASS" started-at="2019-02-07T18:24:47Z" name="initTest">
</test-method>
<test-method status="FAIL" started-at="2019-02-07T18:24:47Z" name="ActListsForContactShowsContactRelatedTasksTest">
</test-method>
</class>
</test>
</suite>
</testng-results>

Текущий XSL:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <Suite>
            <xsl:for-each select="testng-results/suite/test/class/test-method">
                        <Test>
                            <Result_Path> <xsl:value-of select="concat('testngreports/', ../@name, '/', @name)"/> </Result_Path>
                        </Test>
            </xsl:for-each>
        </Suite>
    </xsl:template>
</xsl:stylesheet>

Ожидаемый результат XML:

<?xml version="1.0" encoding="UTF-8"?>
<Suite>
  <Test>
    <Result_Path>testngreports/system.apps.webdriver.tests.crm.mot/CreateTerritoryProposalTest/initTest</Result_Path>
  </Test>
  <Test>
    <Result_Path>testngreports/system.apps.webdriver.tests.crm.mot/CreateTerritoryProposalTest/ActListsForContactShowsContactRelatedTasksTest</Result_Path>
  </Test>
</Suite>

Текущий вывод XML:


<?xml version="1.0" encoding="UTF-8"?>
<Suite>
  <Test>
    <Result_Path>testngreports/system.apps.webdriver.tests.crm.mot.CreateTerritoryProposalTest/initTest</Result_Path>
  </Test>
  <Test>
    <Result_Path>testngreports/system.apps.webdriver.tests.crm.mot.CreateTerritoryProposalTest/ActListsForContactShowsContactRelatedTasksTest</Result_Path>
  </Test>
</Suite>

Резюме:

Токовый выход:

testngreports/system.apps.webdriver.tests.crm.mot.CreateTerritoryProposalTest/initTest

Ожидаемый результат:

testngreports/system.apps.webdriver.tests.crm.mot/CreateTerritoryProposalTest/initTest

Последний '.' символ должен быть заменен на '/'

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

С xsltproc - то есть процессором libxslt - вы можете воспользоваться функцией расширения EXSLT str:tokenize() и выполнить:

<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:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/testng-results">
    <Suite>
        <xsl:for-each select="suite/test/class">
            <xsl:variable name="class-name">
                <xsl:for-each select="str:tokenize(@name, '.')">
                    <xsl:value-of select="."/> 
                    <xsl:choose>
                        <xsl:when test="position() >= last() - 1 ">/</xsl:when>
                        <xsl:otherwise>.</xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:variable>
            <xsl:for-each select="test-method">
                <Test>
                    <Result_Path>
                        <xsl:text>testngreports/</xsl:text>
                        <xsl:value-of select="$class-name"/> 
                        <xsl:value-of select="@name"/> 
                    </Result_Path>
                </Test>
            </xsl:for-each>
        </xsl:for-each>
    </Suite>
</xsl:template>

</xsl:stylesheet>
1 голос
/ 17 апреля 2019

Вероятно, нужна рекурсия. Напишите рекурсивный шаблон T: если указанная строка $ S не содержит «.», То скопируйте ее без изменений; в противном случае пусть $ L будет substring-before ($ S, "."), а $ R будет substring-after ($ S, "."). Если $ R содержит "." затем вернуть конкатенацию $ L, "." и результат рекурсивного вызова T с параметром $ R; в противном случае возвращает объединение $ L, "/" и $ R.

...