XSLT: сортировка по атрибуту дочернего узла не работает - PullRequest
0 голосов
/ 11 апреля 2019

Я просто не могу заставить работать функцию сортировки.

В основном я пытаюсь сделать то же самое, что и XSLT-сортировка по значению атрибута , но это просто не работает

Ввод

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

<result>
  <doc>
    <str name="hash1">EBFF15C2FB15BDD9C069EDF272EF43E738B276AA</str>
    <str name="org_data">
<items>
<orgdata amount ="5433" />
</items>
</str>
</doc>
  <doc>
    <str name="hash1">8CB2237D0679CA88DB6464EAC60DA96345513964</str>
    <str name="org_data">
<items>
<orgdata amount_rur="300"/>
<orgdata amount_rur="100"/>
<orgdata amount_rur="200"/>
<orgdata amount_rur="200" />
</items>
</str>
 </doc>
</result>
</response>

И я пытаюсь что-то вроде этого:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:param name="rta-hashParticipantData1" select = "'8CB2237D0679CA88DB6464EAC60DA96345513964'"  />
    <xsl:param name="rta-hashParticipantData2"  select = "'EBFF15C2FB15BDD9C069EDF272EF43E738B276AA'" />
    <xsl:param name="rta-hashParticipantData3" />
    <xsl:param name="rta-role" select = "'123'"  />

    <xsl:template match="result">
        <xsl:copy>
            <roleName Role="{$rta-role}">
            <xsl:for-each-group select="doc" group-by="str[@name='hash1']">
                    <xsl:choose>
                        <xsl:when test="current-group()/str[@name='hash1']=$rta-hashParticipantData1">
                            <hashData hashName= '1' hashValue="{current-group()/str[@name='hash1']}" >
                                <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                            </hashData>
                        </xsl:when>
                        <xsl:when test="current-group()/str[@name='hash1']=$rta-hashParticipantData2">
                            <hashData hashName= '2' hashValue="{current-group()/str[@name='hash1']}" >
                                <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                            </hashData>
                        </xsl:when>
                        <xsl:when test="current-group()/str[@name='hash1']=$rta-hashParticipantData3">
                            <hashData hashName= '3' hashValue="{current-group()/str[@name='hash1']}" >
                                <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                            </hashData>
                        </xsl:when>
                    </xsl:choose>
            </xsl:for-each-group>
            </roleName>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="photoUrls|str">
        <xsl:apply-templates select="*"/>
    </xsl:template>
   <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
 <xsl:template match="roleName">
    <xsl:copy>
      <xsl:apply-templates select="hashData">
        <xsl:sort select="@hashName"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Итак, я:

1) Группировка данных по значению hash1

2) Добавление некоторой информации (роли и номера хеша) на основе глобальных параметров. Более конкретно, я добавляю элемент hashData с атрибутами hashName (номер хеша) и hashValue (значение хеша для отладки).

3) Очистка вещей 'str'

4) Попытка сортировки данных в одной роли по hashData / @ hashName

Последний не работает (он работает, если я делаю это с другим XSL-ом). Итак, вопрос - как это сделать в том же XSL, и почему это не работает у меня?

Ответы [ 2 ]

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

Одним из подходов может быть определение одного параметра, состоящего из списка хэшей, разделенных запятыми, а затем использование tokenize и index-of для обработки hashName.

Это будет иметьпреимущество удаления xsl:choose и разрешения более 3 параметров тоже.

Попробуйте это XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:param name="rta-role" select = "'123'"  />

    <xsl:param name="rta-hashParticipantData" select="'8CB2237D0679CA88DB6464EAC60DA96345513964,EBFF15C2FB15BDD9C069EDF272EF43E738B276AA'" />

    <xsl:template match="result">
        <xsl:variable name="rta-hashParticipantDataList" select="tokenize($rta-hashParticipantData, ',')" />
        <xsl:copy>
            <roleName Role="{$rta-role}">
                <xsl:for-each-group select="doc" group-by="str[@name='hash1']">
                    <xsl:sort select="index-of($rta-hashParticipantDataList, current-grouping-key())" />
                    <hashData hashName="{index-of($rta-hashParticipantDataList, current-grouping-key())}" hashValue="{current-group()/str[@name='hash1']}" >
                        <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                    </hashData>
                </xsl:for-each-group>
            </roleName>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="photoUrls|str">
        <xsl:apply-templates select="*"/>
    </xsl:template>

   <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

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

Кажется, вы хотите отсортировать результат, который хотите создать, поэтому попробуйте обернуть вашу группировку, создав hashData элементы, в xsl:perform-sort:

<xsl:perform-sort>
  <xsl:sort select="@hashName"/>
  <xsl:for-each-group select="doc" group-by="str[@name='hash1']">
                    <xsl:choose>
                        <xsl:when test="current-group()/str[@name='hash1']=$rta-hashParticipantData1">
                            <hashData hashName= '1' hashValue="{current-group()/str[@name='hash1']}" >
                                <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                            </hashData>
                        </xsl:when>
                        <xsl:when test="current-group()/str[@name='hash1']=$rta-hashParticipantData2">
                            <hashData hashName= '2' hashValue="{current-group()/str[@name='hash1']}" >
                                <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                            </hashData>
                        </xsl:when>
                        <xsl:when test="current-group()/str[@name='hash1']=$rta-hashParticipantData3">
                            <hashData hashName= '3' hashValue="{current-group()/str[@name='hash1']}" >
                                <xsl:apply-templates select="current-group()/str[@name='org_data']" />
                            </hashData>
                        </xsl:when>
                    </xsl:choose>
   </xsl:for-each-group>
</xsl:perform-sort>

Или сгруппировать в переменную, а затем нажмитесодержимое переменной через apply-templates.Ваш шаблон с match="roleName" может быть применен, только если вы создали элементы с таким именем в дереве ввода или во временном дереве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...