2016-12-19 6 views
0

Я хотел бы узнать лучший подход к решению этого решения в xslt 2.0.xslt рекурсивные дочерние узлы с родительским узлом

Вход:

<Root> 
    <Record> 
     <FName>Abc</FName> 
     <MName>FAbc</MName> 
     <Kid> 
      <CName>C1Abc<CName> 
     </Kid> 
     <Kid> 
      <CName>C2Abc<CName> 
     </Kid> 
    </Record> 
    <Record> 
     <FName>Def</FName> 
     <MName>FDef</MName> 
     <Kid> 
      <CName>C1Def<CName> 
     </Kid> 
    </Record> 
    <Record> 
     <FName>Xyz</FName> 
     <MName>FXyz</MName> 
    </Record> 
</Root> 

Выход:

<Root> 
    <Record> 
     <FName>Abc</FName> 
     <MName>FAbc</MName> 
     <CName>C1Abc<CName> 
    </Record> 
    <Record> 
     <FName>Abc</FName> 
     <MName>FAbc</MName> 
     <CName>C2Abc<CName> 
    </Record> 
    <Record> 
     <FName>Def</FName> 
     <MName>FDef</MName> 
     <CName>C1Def<CName> 
    </Record> 
    <Record> 
     <FName>Xyz</FName> 
     <MName>FXyz</MName> 
     <CName></CName> 
    </Record> 
</Root> 

XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    version="2.0"> 

    <xsl:template match="Root"> 
     <Root> 
      <xsl:apply-templates select="Record"> 
      </xsl:apply-templates> 
     </Root> 
    </xsl:template> 

    <xsl:template match="Record"> 
     <xsl:choose> 
      <xsl:when test="Kid"> 
       <xsl:apply-templates select="Kid">        
       </xsl:apply-templates> 
      </xsl:when> 
      <xsl:otherwise> 
       <Record> 
        <FName> 
         <xsl:value-of select="FName"/> 
        </FName> 
        <MName> 
         <xsl:value-of select="MName"/> 
        </MName>   
        <CName> 
         <xsl:value-of select="Kid/CName"/> 
        </CName> 
       </Record>         
      </xsl:otherwise> 
     </xsl:choose>  
    </xsl:template> 

    <xsl:template match="Kid"> 
     <Record> 
      <FName> 
       <xsl:value-of select="../FName"/> 
      </FName> 
      <MName> 
       <xsl:value-of select="../MName"/> 
      </MName> 
      <CName> 
       <xsl:value-of select="CName"/> 
      </CName>    
     </Record>    
    </xsl:template> 
</xsl:stylesheet> 

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

+0

Будет ли всегда быть '' FName' и MName' всегда будет присутствовать? Или может ли какой-либо из дочерних элементов быть дополнительным? –

+0

У вас действительно проблемы с производительностью? Профилировали ли вы свой существующий код с помощью вашего XSLT-процессора, чтобы узнать, какой код необходимо улучшить? –

+0

@Tim C, все дочерние элементы являются необязательными, но должен быть пустой тег и , если нет значения. – user3836593

ответ

0

Вы можете переписать

<xsl:template match="Record"> 
    <xsl:choose> 
     <xsl:when test="Kid"> 
      <xsl:apply-templates select="Kid">        
      </xsl:apply-templates> 
     </xsl:when> 
     <xsl:otherwise> 
      <Record> 
       <FName> 
        <xsl:value-of select="FName"/> 
       </FName> 
       <MName> 
        <xsl:value-of select="MName"/> 
       </MName>   
       <CName> 
        <xsl:value-of select="Kid/CName"/> 
       </CName> 
      </Record>         
     </xsl:otherwise> 
    </xsl:choose>  
</xsl:template> 

в

<xsl:template match="Record[not(Kid)]"> 
      <Record> 
       <FName> 
        <xsl:value-of select="FName"/> 
       </FName> 
       <MName> 
        <xsl:value-of select="MName"/> 
       </MName>   
       <CName></CName> 
      </Record>          
</xsl:template> 

<xsl:template match="Record[Kid]"> 
    <xsl:apply-templates select="Kid"/> 
</xsl:template> 
+0

Спасибо Мартину за ваш комментарий. BTW, есть где-то переписать ../ (чтобы вернуться от текущего узла), или это правильный подход? – user3836593

+0

Я не вижу необходимости переписывать доступ к родительскому узлу с помощью '..'. Переписанный мной вариант также в основном косметический, но в целом я думаю, что использование шаблонов совпадений шаблонов с предикатами для различения различных структур является более ясным и более элегантным, чем использование 'xsl: choose/xsl: when' внутри одного шаблона. –

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