Concat несколько узлов xsl - PullRequest
3 голосов
/ 26 апреля 2011

Мой XML:

<?xml version="1.0"?>
<Result>
   <Answer questionId="Servicios">Auditoría|Asesoría en Impuestos|</Answer>
   <Answer questionId="Servicios">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
</Result>

Я хочу объединить каждую node() в переменную UNIQUE (например, <xsl:variable name = "var"/>), используя xsl:for-each или что-то в этом роде, а затем сосчитать "|" char используя это:

<xsl:variable name="total" select="string-length(string($var))-string-length(translate(string($var),'|',''))"/>

Если я сделаю это:

    <xsl:value-of select ="//Result/Answer[@questionId = 'Servicios']//text()"/>
<!--The return is something like an array-->
<!--[1]Auditoría|Asesoría en Impuestos|-->
<!--[2]Auditoría|Outsourcing|Asesoría en RRHH|-->
<!--and the result is '2' it only select the [1] and i need all of them, [1] and [2] in this case-->

Я думаю, что должен объединить все значения с xsl:for-each

я использую xslt version="1.0"

Буду признателен за любую помощь! Спасибо!

Ответы [ 3 ]

3 голосов
/ 26 апреля 2011

Самое короткое / простое XSLT-преобразование, которое приводит к желаемому результату (объединение строковых значений элементов Answer) это :

<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="/">
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

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

<Result>
    <Answer questionId="Servicios">Auditoría|Asesoría en Impuestos|</Answer>
    <Answer questionId="Servicios">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
</Result>

точно желаемый, правильный результат получается :

Auditoría|Asesoría en Impuestos|Auditoría|Outsourcing|Asesoría en RRHH|

Объяснение

  1. Строковое значение корневого узла / является объединением всех его потомков текстовых узлов.

  2. Директива <xsl:strip-space elements="*"/> удаляет из документа XML все нежелательные текстовые узлы только для пробелов.

Обновление : Если документ XML более сложный, чем предоставленный, и требуется некоторая фильтрация, вот общее и простое решение, использующее ту же идею:

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

 <xsl:variable name="vStrings">
  <xsl:copy-of select="/*/*[@questionId='Servicios']"/>
 </xsl:variable>

 <xsl:template match="/">
  <xsl:value-of select="$vStrings"/>
 </xsl:template>
</xsl:stylesheet>

при применении к этому XML-документу (обратите внимание, что мы должны исключить второй <Answer>):

<Result>
    <Answer questionId="Servicios">Auditoría|Asesoría en Impuestos|</Answer>
    <Answer questionId="X">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
    <Answer questionId="Servicios">Auditoría|Outsourcing|Asesoría en RRHH|</Answer>
</Result>

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

Auditoría|Asesoría en Impuestos|Auditoría|Outsourcing|Asesoría en RRHH|
2 голосов
/ 26 апреля 2011

Для данного документа вы можете объединить довольно просто с помощью normalize-space(Result), но имейте в виду, что в вашем коде счета это даже не требуется.

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:value-of select="string-length(Result)-
            string-length(translate(Result,'|',''))"/> 
    </xsl:template>
</xsl:stylesheet>

просто выводитрезультат «5» без использования for-each.

ОБНОВЛЕНИЕ после редактирования ОП:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:variable name="var">
            <xsl:apply-templates select="//Answer[@questionId='Servicios']"/>
        </xsl:variable>
        <xsl:variable name="total" select="string-length($var)-
            string-length(translate($var,'|',''))"/>
        <xsl:value-of select="$total"/> 
    </xsl:template>
</xsl:stylesheet> 
0 голосов
/ 26 апреля 2011
<!-- This will concatenate the nodes with a comma in between.  Is this what you want?-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
    <xsl:template match="/*">
      <xsl:for-each select="Answer/text()">
        <xsl:value-of select="."/>
        <xsl:text>,</xsl:text>
      </xsl:for-each>
    </xsl:template>
  </xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...