XSLT создает новый массив, перебирая существующий массив

Я пытаюсь собрать интересующие меня строки, перебирая массив объектов и создавая новый массив. Я бы использовал этот новый массив позже в своем преобразовании для генерации выходных данных.

Ниже мой код:

          <xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:fn="http://www.w3.org/2005/xpath-functions"
        xmlns:map="http://www.w3.org/2005/xpath-functions/map"
        xmlns:array="http://www.w3.org/2005/xpath-functions/array"
        version="3.0">
        <xsl:output method="text"/>
        <xsl:strip-space elements="*" />
        <xsl:template name="test" match="/">
            <xsl:param name="data" select="data"></xsl:param>
            <xsl:variable name="myData" select="$data" />
    
          <xsl:variable name="inputArray" select="array{'John', 'Peter'}"/>
           <xsl:variable name="myArray" select="array{}"/>
          
            <xsl:for-each select="1 to array:size($inputArray)">
            <xsl:variable name="personName" select="array:get($inputArray, .)" />
            <xsl:value-of select="$personName" />
             <xsl:variable name="myArray" select="array:append($myArray, personName)" />
            </xsl:for-each>
    <!--       <xsl:variable name="myArray" select="array:append($myArray, 'John')" />
          <xsl:variable name="myArray" select="array:append($myArray, 'Peter')" /> -->
          
          <xsl:for-each select="1 to array:size($myArray)">
          <xsl:value-of select="test" />
            <xsl:text>Person name is : </xsl:text>
            <xsl:value-of select="array:get($myArray,.)" />
        </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>

При этом значения не добавляются в myArray и даже не вводятся в блок for-each для вывода «тестовой» строки.

Источником входного массива является массив объектов, как показано ниже:

        map {"persons": [map {
                    "name": "John",
                    "age": 33,
                    "residence":"Permanent" 
                    }, map {
                    
                    "name": "Peter",
                    "age": 36,
                    "residence":"Temporary"
                        }
            ]
    }

Я бы читал этот массив, используя итерацию map:get($persons) и собирал имена в myArray.

1 ответ

Используйте XPath 3.1, не думайте в процедурных терминах, таких как итерация, тогда вы можете просто сделать, например

      <xsl:variable name="inputArray" select="array{'John', 'Peter'}"/>
<xsl:variable name="myArray" select="array{ $inputArray?* }"/>

Мы также могли бы выразить это с помощьюfold-left, или, если вы действительно хотите «повторить»,xsl:iterate, но я не вижу в этом никакой необходимости.

Вся таблица стилей может быть, например,

      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">
  
    <xsl:output method="text"/>
    <xsl:template name="test" match="/">
        
      <xsl:variable name="inputArray" select="array{'John', 'Peter'}"/>
      <xsl:variable name="myArray" select="array{ $inputArray?* }"/>
      
      <xsl:value-of select="$myArray?* ! ('Person name is: ' || .)" separator="&#10;"/>
      
    </xsl:template>
    
</xsl:stylesheet>

Для обработки карты вы по-прежнему можете использовать XPath 3.1 для построения массива на основе свойств:

      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">
  
    <xsl:output method="text"/>
    <xsl:template name="test" match="/">
        
      <xsl:variable name="inputObject" select='map {"persons": [map {
                    "name": "John",
                    "age": 33,
                    "residence":"Permanent" 
                    }, map {
                    
                    "name": "Peter",
                    "age": 36,
                    "residence":"Temporary"
                        }
            ]
    }'/>
      <xsl:variable name="myArray" select="array{ $inputObject?persons?*?name }"/>
      
      <xsl:value-of select="$myArray?* ! ('Person name is: ' || .)" separator="&#10;"/>
      
    </xsl:template>
    
</xsl:stylesheet>
Другие вопросы по тегам