Переименование повторяющихся имен массивов в XSLT 1.0

#xslt #xslt-1.0 #rename #jsonx

#xslt #xslt-1.0 #переименовать #jsonx

Вопрос:

У меня есть ниже список с массивами, имеющими одинаковое имя (json: имя массива =»член»). Я пытаюсь переименовать их во что-то значимое (json:array name =»member1″), чтобы они оставались уникальными значениями. Я пытаюсь использовать шаблон идентификации.

Ввод:

 <json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <json:array xmlns:dpfunc="http://www.datapower.com/extensions/functions" xmlns:str="http://exslt.org/strings" name="benefits">
      <json:object>
         <json:string name="ArrayCode">A</json:string>
         <json:array name="member">
            <json:object>
               <json:string name="memberID">A-001</json:string>
            </json:object>
         </json:array>
         <json:array name="member">
            <json:object>
               <json:string name="memberID">A-002</json:string>
            </json:object>
         </json:array>
         <json:array name="member">
            <json:object>
               <json:string name="memberID">A-003</json:string>
            </json:object>
         </json:array>
      </json:object>
      <json:object>
         <json:string name="ArrayCode">B</json:string>
         <json:array name="member">
            <json:object>
               <json:string name="memberID">B-001</json:string>
            </json:object>
         </json:array>
         <json:array name="member">
            <json:object>
               <json:string name="memberID">B-002</json:string>
            </json:object>
         </json:array>
         <json:array name="member">
            <json:object>
               <json:string name="memberID">B-003</json:string>
            </json:object>
         </json:array>
      </json:object>
   </json:array>
</json:object>
 

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

    <json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <json:array xmlns:dpfunc="http://www.datapower.com/extensions/functions" xmlns:str="http://exslt.org/strings" name="benefits">
      <json:object>
         <json:string name="ArrayCode">A</json:string>
         <json:array name="member1">
            <json:object>
               <json:string name="memberID">A-001</json:string>
            </json:object>
         </json:array>
         <json:array name="member2">
            <json:object>
               <json:string name="memberID">A-002</json:string>
            </json:object>
         </json:array>
         <json:array name="member3">
            <json:object>
               <json:string name="memberID">A-003</json:string>
            </json:object>
         </json:array>
      </json:object>
      <json:object>
         <json:string name="ArrayCode">B</json:string>
         <json:array name="member1">
            <json:object>
               <json:string name="memberID">B-001</json:string>
            </json:object>
         </json:array>
         <json:array name="member2">
            <json:object>
               <json:string name="memberID">B-002</json:string>
            </json:object>
         </json:array>
         <json:array name="member3">
            <json:object>
               <json:string name="memberID">B-003</json:string>
            </json:object>
         </json:array>
      </json:object>
   </json:array>
</json:object>
 

XSLT Я попытался с помощью шаблона идентификации и для каждого перебирать список массивов.

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" xmlns:dp="http://www.datapower.com/extensions" xmlns:dpfunc="http://www.datapower.com/extensions/functions" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:str="http://exslt.org/strings" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd" extension-element-prefixes="dp" exclude-result-prefixes="xsl fo xs fn dp date">
   
   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
   </xsl:template>
   
   
   <xsl:template match="json:array/@name">
      <xsl:for-each select="json:object/json:array">
         <xsl:attribute name="@name{position()}">
            <xsl:value-of select="@name"/>
         </xsl:attribute>
      </xsl:for-each>  
   </xsl:template>
   
</xsl:stylesheet>
 

Никаких изменений при вводе с помощью приведенного выше кода не происходит. Я думаю, что использование for-each здесь неверно. Но как я могу получить доступ к именам массивов, вложенных внутрь.

Комментарии:

1. Используя имя массива, чтобы оно применялось только к внутреннему массиву и xsl: number вместо position — я вижу результат, как и ожидалось. Спасибо.

Ответ №1:

Возможно

 <xsl:template match="json:array[@name = 'member']">
    <xsl:copy>
        <xsl:attribute name="name">
            <xsl:value-of select="@name"/>
            <xsl:number/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
 

помогает, если вы знаете имя массива.

Ответ №2:

Если вы хотите использовать позицию json:array внутри его родительского json:object элемента, тогда ваш шаблон должен совпадать json:array — скажем:

 <xsl:template match="json:array">
    <xsl:copy>
        <xsl:attribute name="name">
            <xsl:value-of select="@name" />
            <xsl:value-of select="position()" />
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
 

Однако вам нужно иметь в виду, что:

  1. это приведет к нумерации ВСЕХ json:array элементов, включая один верхнего уровня; и
  2. позиция первого json:array в вашем json:object массиве равна 2, а не 1. Первую позицию занимает json:string элемент.

Комментарии:

1. Вышеуказанный подход дает member4, member6, member8 и т.д. При применении к входному XML. Вместо применения атрибута name, который уже указан выше, могу ли я каким-либо образом применить исключительно к json: array, присутствующему внутри, чтобы он мог быть member1, member2, , member3.

2. Нет, он предоставляет member2, member3, member4 и т. Д. — См.: xsltfiddle . liberty-development.net/6qjt5R8 . Что касается обработки только некоторых элементов массива, вам необходимо предоставить правила, которые можно использовать для этого. Все, что у нас есть, это один пример. Я не предполагал, что можно жестко кодировать имя массива (как это было сделано в принятом ответе). Если бы я хотел предположить, что входные данные всегда будут выглядеть как в примере, я бы использовал position() - 1 для получения ожидаемой нумерации.

3. Я думаю, что использование xsl:number здесь более надежно, это делает ответ менее чувствительным к пробелам во входных данных, а также к другим посторонним элементам узлов.