2015-08-26 5 views
2

У меня есть этот файл XML с датами, сеансами и подтемами. У меня есть первые два уровня, которые работают нормально, но я не могу правильно набрать третий уровень.Группировка данных на 3 уровнях с использованием XSLT 1.0

Уровень 1 группы по дате Все сессии на один день должны быть сгруппированы в соответствии с этой датой

Уровень 2 группы по Session_Number Все Sessions с тем же номером, должны быть сгруппированы вместе.

Уровень 3 должен группироваться по Abstract_Title. Если Abstract_Title тот же, он должен появиться один раз со всеми перечисленными в нем авторами.

Вот мой XSLT:

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

<xsl:key name="sessions-by-startDate" match="session" use="startDate"/> 
<xsl:key name="sessions-by-Number" match="session" use="concat(startDate, '|', Session_Number)"/> 
<xsl:key name="sessions-by-Abstract" match="stamp" use="concat(startDate, '|', Session_Number, '|', Abstract_Title)"/> 
<xsl:template match="sessions"> 
<Guide>  
<xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-startDate', startDate)[1])]"> 
<xsl:text> 
</xsl:text><SessionDay> 
<startDate><xsl:value-of select="startDate"/></startDate> 

<xsl:for-each select="key('sessions-by-startDate', startDate)[generate-id() = generate-id(key('sessions-by-Number', concat(startDate, '|', Session_Number))[1])]"> 
<sessions> 
<xsl:apply-templates select="startTime"/> 
<xsl:apply-templates select="Session_Number" /> 
<xsl:apply-templates select="Session_Title"/><xsl:text> 
</xsl:text><TopicTitle>Topics &amp; Faculty</TopicTitle> 

<xsl:for-each select="key('sessions-by-Number', concat(startDate, '|', Session_Number))"> 


<xsl:for-each 
select="key('sessions-by-Number', concat(startDate, '|', Session_Number))[count(. | key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))[1]) = 1]"> 
<xsl:sort select="Abstract_Title"/> 
<xsl:text> 
</xsl:text><session> 
<xsl:apply-templates select="Abstract_Title"/> 

<xsl:for-each select="key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))"> 
<xsl:apply-templates select="Author_LastName"/> 
</xsl:for-each> 
</session> 
</xsl:for-each> 


</xsl:for-each> 
</sessions> 

</xsl:for-each> 
</SessionDay> 
</xsl:for-each> 
</Guide>  
</xsl:template> 

<xsl:template match="startDate"> 
<startDate><xsl:value-of select="."/></startDate></xsl:template> 

<xsl:template match="Session_Title"><xsl:text> 
</xsl:text><Session_Title><xsl:value-of select="."/></Session_Title> </xsl:template> 

<xsl:template match="Session_Number"><xsl:text> 
Session Number </xsl:text><Session_Number><xsl:value-of select="."/> </Session_Number></xsl:template> 

<xsl:template match="Abstract_Title"><Abstract_Title><xsl:value-of select="."/> </Abstract_Title></xsl:template> 

<xsl:template match="Author_LastName"> 
<Author_LastName><xsl:value-of select="."/></Author_LastName></xsl:template> 

</xsl:stylesheet> 

Ниже приведен пример XML:

<?xml version="1.0" encoding="utf-8"?><sessions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<session><startDate>10/24/2015</startDate><Session_Number>92</Session_Number><Session_Title>Sleep Medicine</Session_Title><Abstract_Title>Concluding Remarks</Abstract_Title><Author_LastName>Stoller</Author_LastName></session> 
<session><startDate>10/24/2015</startDate><Session_Number>92</Session_Number><Session_Title>Sleep Medicine</Session_Title><Abstract_Title>Welcome and Introduction</Abstract_Title><Author_LastName>Stoller</Author_LastName></session> 
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Roth</Author_LastName></session> 
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Eling</Author_LastName></session> 
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Bell</Author_LastName></session> 
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>The Role of EBUS</Abstract_Title><Author_LastName>Silvestri</Author_LastName></session> 
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>Lung Cancer Staging</Abstract_Title><Author_LastName>Liberman</Author_LastName></session> 
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>Lung Cancer Staging</Abstract_Title><Author_LastName>Hong</Author_LastName></session> 
<session><startDate>10/25/2015</startDate><Session_Number>9</Session_Number><Session_Title>Non-small Cell Lung Cancer??</Session_Title><Abstract_Title>Imaging </Abstract_Title><Author_LastName>Duong</Author_LastName></session> 
</sessions> 

Результирующий XML должен выглядеть следующим образом:

<?xml version="1.0" encoding="utf-8"?><Guide> 
<SessionDay> 
<startDate>10/24/2015</startDate> 
<sessions>Session Number <Session_Number>92</Session_Number> 
<Session_Title>Sleep Medicine</Session_Title>  
<TopicTitle>Topics &amp; Faculty</TopicTitle> 

<session><Abstract_Title>Concluding Remarks</Abstract_Title> 
<Author_LastName>Stoller</Author_LastName></session> 

<session><Abstract_Title>Welcome and Introduction</Abstract_Title>  
<Author_LastName>Stoller</Author_LastName></session> 
</sessions> 

<sessions>Session Number <Session_Number>568</Session_Number> 
<Session_Title>Hands-on Simulation</Session_Title> 
<TopicTitle>Topics &amp; Faculty</TopicTitle> 

<session><Abstract_Title>Airway</Abstract_Title>  
<Author_LastName>Roth</Author_LastName> 
<Author_LastName>Eling</Author_LastName> 
<Author_LastName>Bell</Author_LastName></session> 
</sessions></SessionDay> 

<SessionDay><startDate>10/25/2015</startDate> 
<sessions>Session Number <Session_Number>1</Session_Number> 
<Session_Title>Diagnosis of Lung Cancer</Session_Title> 
<TopicTitle>Topics &amp; Faculty</TopicTitle> 

<session><Abstract_Title>The Role of EBUS</Abstract_Title> 
<Author_LastName>Silvestri</Author_LastName></session> 

<session><Abstract_Title>Lung Cancer Staging</Abstract_Title> 
<Author_LastName>Liberman</Author_LastName></session> 

<session><Abstract_Title>Lung Cancer Diagnosis</Abstract_Title> 
<Author_LastName>Hong</Author_LastName></session></sessions> 

<sessions>Session Number <Session_Number>9</Session_Number> 
<Session_Title>Non-small Cell Lung Cancer??</Session_Title> 
<TopicTitle>Topics &amp; Faculty</TopicTitle> 

<session><Abstract_Title>Imaging</Abstract_Title> 
<Author_LastName>Duong</Author_LastName></session> 
</sessions></SessionDay> 
</Guide> 

Мой текущий XSLT создает первый две группы отлично. Но я получаю повторяющиеся элементы Abstract_Title. Вместо этого он должен иметь только один уникальный элемент Abstract_Title и список всех уникальных имен авторов после этого.

Мне нужно добавить третий ключ и сгенерировать еще один идентификатор. Но я не знаю, где его вставить или как это нужно писать. Любая помощь будет оценена

+0

Я обновил XSLT, чтобы показать свой третий КЛЮЧ. Но он не группирует уникальные элементы . Кто-нибудь может понять, что случилось с третьим ключом? –

ответ

1

Существовали несколько вопросов с вашей XSLT:

1.) xsl:key name="sessions-by-Abstract" было соответствие stamp вместо session, так что ключ не был ничего соответствия.

2.) Для каждого из <xsl:for-each select="key('sessions-by-Number', concat(startDate, '|', Session_Number))"> был выбран элемент из ключа «Сеансы по номеру», а затем в качестве критериев для выбора из одного и того же ключа в следующем xsl:for-each, что приводит к дублированию.

3.) Если вы намерены вставить разрыв строки в свой вывод, было бы лучше использовать объект вместо разрыва строки. Например: <xsl:text>&#xA;</xsl:text>. Таким образом, если ваш XSLT должен быть отформатирован в коде, вы не рискуете потерять разрыв строки или добавление дополнительных пространств в свой вывод. Однако, если вы просто пытались лучше форматировать выходной XML, было бы проще использовать <xsl:output indent="yes"/>, что будет довольно печатать (форматировать и отступать) XML.

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

    <xsl:key name="sessions-by-startDate" match="session" use="startDate"/> 
    <xsl:key name="sessions-by-Number" match="session" use="concat(startDate, '|', Session_Number)"/> 
    <xsl:key name="sessions-by-Abstract" match="session" use="concat(startDate, '|', Session_Number, '|', Abstract_Title)"/> 

    <xsl:template match="sessions"> 
     <Guide>  
      <xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-startDate', startDate)[1])]"> 
       <xsl:text>&#xA;</xsl:text> 
       <SessionDay> 
       <startDate><xsl:value-of select="startDate"/></startDate> 
       <xsl:for-each select="key('sessions-by-startDate', startDate)[generate-id() = generate-id(key('sessions-by-Number', concat(startDate, '|', Session_Number))[1])]"> 
        <sessions> 
         <xsl:apply-templates select="startTime"/> 
         <xsl:apply-templates select="Session_Number"/> 
         <xsl:apply-templates select="Session_Title"/> 
         <xsl:text>&#xA;</xsl:text> 
         <TopicTitle>Topics &amp; Faculty</TopicTitle> 
         <xsl:for-each 
          select="key('sessions-by-Number', concat(startDate, '|', Session_Number))[count(. | key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))[1]) = 1]"> 
          <xsl:sort select="Abstract_Title"/> 
          <xsl:text>&#xA;</xsl:text> 
          <session> 
           <xsl:apply-templates select="Abstract_Title"/> 

           <xsl:for-each 
            select="key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))"> 
            <xsl:apply-templates select="Author_LastName"/> 
           </xsl:for-each> 
          </session> 
         </xsl:for-each> 
        </sessions> 
       </xsl:for-each> 
       </SessionDay> 
      </xsl:for-each> 
     </Guide>  
    </xsl:template> 

    <xsl:template match="startDate"> 
     <startDate><xsl:value-of select="."/></startDate> 
    </xsl:template> 

    <xsl:template match="Session_Title"> 
     <xsl:text>&#xA;</xsl:text> 
     <Session_Title><xsl:value-of select="."/></Session_Title>  
    </xsl:template> 

    <xsl:template match="Session_Number"> 
     <xsl:text>Session Number </xsl:text> 
     <Session_Number> 
      <xsl:value-of select="."/> 
     </Session_Number> 
    </xsl:template> 

    <xsl:template match="Abstract_Title"><Abstract_Title><xsl:value-of select="."/>  
     </Abstract_Title> 
    </xsl:template> 

    <xsl:template match="Author_LastName"> 
     <Author_LastName><xsl:value-of select="."/></Author_LastName> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Спасибо. Я проверю ваши предложения. FYI, я использую разрывы строк, потому что я импортирую в Adobe InDesign. Я должен проверить, соблюдает ли InDesign предложенные сущности. Он выполняет разрывы строк, используя записи xsl: text. –

+0

Не могу поверить, что я пропустил эту ошибку в ключе. Спасибо за другие предложения. Тем не менее, объект ' ' не работал в InDesign. Я собираюсь попробовать другую сущность. Мне повезло с другими. –

+0

'&xA;' - это символ новой строки.Если вам нужен возврат каретки, попробуйте ' ' –

Смежные вопросы