2016-06-02 1 views
1

Ищет анализ пространства имен из полного имени класса в xml. ПримерXSLT - извлечь весь текст, но последний подраздел

данных:

<results> 
    <test-case name="Co.Module.Class.X"> 
</results> 

Конечный результат (переход в формат CSV): ,Co.Module.Class

стилевых:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"> 
    <xsl:output method="text" indent="yes" encoding="ISO-8859-1"/> 
    <xsl:param name="delim" select="','" /> 
    <xsl:param name="quote" select="'&quot;'" /> 
    <xsl:param name="break" select="'&#xA;'" /> 
    <xsl:template match="/"> 
FullTestName, Namespace 
<xsl:apply-templates select="//test-case" /> 
    </xsl:template> 

    <xsl:template match="test-case"> 
    <xsl:apply-templates /> 
     <xsl:value-of select="@name" /> 
     <xsl:value-of select="$delim" /> 
     <xsl:value-of select="function to go here for nameWithJustNamespace" /> 
     <xsl:value-of select="$break" />  
    </xsl:template> 

Я понимаю, что процесс будет нужен последний индекс». " для вызова один раз, но я не нахожу XSLT, чтобы иметь эту функцию. Как это сделать?

+0

Я думаю, что вы должны дать больше информации, как входные данные, таблица стилей xsl, вывод и желаемый результат, минимальный полный проверяемый пример ... (MCVE) –

ответ

0

Чтобы сделать это в чистом XSLT 1.0, вам нужно вызвать именованный рекурсивный шаблон, например:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" encoding="UTF-8"/> 

<xsl:template match="/results"> 
    <xsl:call-template name="remove-last-token"> 
     <xsl:with-param name="text" select="test-case/@name"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="remove-last-token"> 
    <xsl:param name="text"/> 
    <xsl:param name="delimiter" select="'.'"/> 
    <xsl:value-of select="substring-before($text, $delimiter)"/> 
    <xsl:if test="contains(substring-after($text, $delimiter), $delimiter)"> 
     <xsl:value-of select="$delimiter"/> 
     <xsl:call-template name="remove-last-token"> 
      <xsl:with-param name="text" select="substring-after($text, $delimiter)"/> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 
+0

[Ну, я думаю, нет.] (ht ф: //stackoverflow.com/questions/37526503/xslt-family-tree/37526892#comment62562181_37526892) –

0

Это чисто XSLT 1.0 преобразование (короче, не условный XSLT операции, один шаблон):

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

    <xsl:template match="test-case[contains(@name, '.')]"> 
    <xsl:param name="pDotIndex" select="0"/> 

    <xsl:variable name="vNextToken" 
     select="substring-before(substring(@name, $pDotIndex+1), '.')"/> 
    <xsl:value-of select="concat(substring('.', 2 - ($pDotIndex > 0)),$vNextToken)"/> 
    <xsl:variable name="vNewDotIndex" select="$pDotIndex+string-length($vNextToken)+1"/> 
    <xsl:apply-templates 
     select="self::node()[contains(substring(@name,$vNewDotIndex+1), '.')]"> 
    <xsl:with-param name="pDotIndex" select="$vNewDotIndex"/> 
    </xsl:apply-templates> 
    </xsl:template> 
</xsl:stylesheet> 

WH ен применяется на поставленном XML документа:

<results> 
    <test-case name="Co.Module.Class.X"/> 
</results> 

производит разыскиваемого, правильный результат:

Co.Module.Class 

Часть 2

С небольшими изменениями следующие преобразования производит полный CSV:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

    <xsl:template match="test-case[contains(@name, '.')]"> 
    <xsl:param name="pDotIndex" select="0"/> 

    <xsl:variable name="vNextToken" 
     select="substring-before(substring(@name, $pDotIndex+1), '.')"/> 
    <xsl:value-of select="concat(substring(',', 2 - (position() > 1)), 
           substring('.', 2 - ($pDotIndex > 0)), $vNextToken)"/> 
    <xsl:variable name="vNewDotIndex" select="$pDotIndex+string-length($vNextToken)+1"/> 
    <xsl:apply-templates 
     select="self::node()[contains(substring(@name,$vNewDotIndex+1), '.')]"> 
    <xsl:with-param name="pDotIndex" select="$vNewDotIndex"/> 
    </xsl:apply-templates> 
    </xsl:template> 
</xsl:stylesheet> 

При нанесении на этот XML-документ:

<results> 
    <test-case name="Co.Module.Class.X"/> 
    <test-case name="Co2.Module2.Class2.Y"/> 
    <test-case name="Co3.Module3.Class3.Z"/> 
</results> 

разыскиваемый, правильно (CSV) результат производится:

Co.Module.Class,Co2.Module2.Class2,Co3.Module3.Class3 
Смежные вопросы