2016-12-14 12 views
0

XMLXSLT Группирование с SUM вопрос, когда первый подузел не существует

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="State.xsl" ?> 

<StateData> 
<States>  
    <State> 
     <StateName>State1</StateName> 
     <Districts> 
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>A</DistrictName>    
       <Population>10000</Population>    
      </District>   
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>B</DistrictName>  
       <Population>5000</Population>     
      </District>  
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>A</DistrictName> 
       <Population>2000</Population>    
      </District>     
     </Districts> 
    </State> 
    <State> 
     <StateName>State2</StateName> 
     <Districts> 
      <District> 
       <TranslatedDistrictName>AC</TranslatedDistrictName> 
       <DistrictName>C</DistrictName> 
       <Population>8000</Population>    
      </District>   
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>B</DistrictName>  
       <Population>5500</Population>     
      </District>  
      <District> 
       <TranslatedDistrictName>AP</TranslatedDistrictName> 
       <DistrictName>A</DistrictName> 
       <Population>1000</Population>    
      </District> 
     </Districts> 
    </State> 
</States> 
</StateData> 

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:key name="district-by-state" match="District" use="concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))])" /> 
    <xsl:template match="StateData"> 
     <xsl:for-each select="States/State">     

       <xsl:for-each select="Districts/District[count(. | key('district-by-state', concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))]))[1]) = 1]">  
        <hr/>     
        - <xsl:value-of select="concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))])"/> 
        --<xsl:value-of select="sum(key('district-by-state', concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))]))/Population)" /> 
       </xsl:for-each> 
      <hr/> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Результат

  • AT --225 00

  • AC --8000

  • AP --1000

В настоящее время, это работает идеально, но в тот момент я добавляю новое состояние, имеющее не район SUM не не работает должным образом.

Примечание. Добавлено новое государство, в котором не используется бирка округов «Район1».

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="State.xsl" ?> 

<StateData> 
<States> 
    <State> 
     <StateName>State3</StateName> 
     <Districts1> 
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>A</DistrictName>    
       <Population>10000</Population>    
      </District>   
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>B</DistrictName>  
       <Population>5000</Population>     
      </District>  
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>A</DistrictName> 
       <Population>2000</Population>    
      </District>     
     </Districts1> 
    </State> 
    <State> 
     <StateName>State1</StateName> 
     <Districts> 
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>A</DistrictName>    
       <Population>10000</Population>    
      </District>   
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>B</DistrictName>  
       <Population>5000</Population>     
      </District>  
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>A</DistrictName> 
       <Population>2000</Population>    
      </District>     
     </Districts> 
    </State> 
    <State> 
     <StateName>State2</StateName> 
     <Districts> 
      <District> 
       <TranslatedDistrictName>AC</TranslatedDistrictName> 
       <DistrictName>C</DistrictName> 
       <Population>8000</Population>    
      </District>   
      <District> 
       <TranslatedDistrictName>AT</TranslatedDistrictName> 
       <DistrictName>B</DistrictName>  
       <Population>5500</Population>     
      </District>  
      <District> 
       <TranslatedDistrictName>AP</TranslatedDistrictName> 
       <DistrictName>A</DistrictName> 
       <Population>1000</Population>    
      </District> 
     </Districts> 
    </State> 
</States> 
</StateData> 

Результат

  • AC --8000
  • AP --1000

Здесь SUM для района AT отсутствует.

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

AT --22500 AC --8000 AP --1000

+0

* Не существует * и * существует под другим именем * две разные вещи , –

ответ

0

Если вы не хотите, чтобы забрать District элементы под Districts1 элементов, то одно решение чтобы изменить ключ только соответствовать District элементов под Districts элементов

<xsl:key name="district-by-state" match="Districts/District" use="concat(TranslatedDistrictName, 
        DistrictName[not(string(../TranslatedDistrictName))])" /> 

Вы также можете изменить xsl:for-each только выбрать State элементы с ребенком Districts узлы

<xsl:for-each select="States/State[Districts]"> 

Попробуйте XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:key name="district-by-state" match="Districts/District" use="concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))])" /> 

    <xsl:template match="StateData"> 
     <xsl:for-each select="States/State[Districts]">     

       <xsl:for-each select="Districts/District[count(. | key('district-by-state', concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))]))[1]) = 1]">  
        <hr/>     
        - <xsl:value-of select="concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))])"/> 
        --<xsl:value-of select="sum(key('district-by-state', concat(TranslatedDistrictName, 
         DistrictName[not(string(../TranslatedDistrictName))]))/Population)" /> 
       </xsl:for-each> 
      <hr/> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Я не хочу выбирать Districts1, но хотел бы увидеть результат AT (внутри State1), который является частью тега Districts. Я указал на проблему, что в тот момент, когда мы добавляем Districts1 в xml, он игнорирует все теги Districts внутри этого состояния. – Manish

+0

Мои извинения @ Мишень, я неправильно понял вопрос. Однако я переписал свой ответ другим способом. –

+0

Немного больше объяснений .. Кажется, я не могу лучше объяснить сценарий. – Manish