2016-04-02 32 views
4

xml(以下に示す)があります。ノード(ref_name_1、ref_name_2、ref_name_3)にテキストが含まれている場合、xsltを使用して対応するノードを生成し、属性のid 1,2などのid番号。私は解決策を見つけようとしましたが、stackoverflow上でさえもこれに関連する何かを見つけられませんでした。for-eachを使用せずにxslt 2.0の変数をインクリメント

サンプルXML

<?xml version="1.0" encoding="UTF-8"?> 
<reference> 
    <ref_name_1>reference1</ref_name_1> 
    <ref_company_1>company1</ref_company_1> 
    <ref_position_1>position3</ref_position_1> 
    <ref_name_2 /> 
    <ref_company_2>company2</ref_company_2> 
    <ref_position_2>position2</ref_position_2> 
    <ref_name_3>reference3</ref_name_3> 
    <ref_company_3>company3</ref_company_3> 
    <ref_position_3>position3</ref_position_3> 
</reference> 

予想される出力:

<?xml version="1.0" encoding="UTF-8"?> 
<services> 
    <service name="reference" id="1"> 
     <name>reference1</name> 
     <company>company1</company> 
     <position>position1</position> 
    </service> 
    <service name="reference" id="2"> 
     <name>reference3</name> 
     <company>company3</company> 
     <position>position3</position> 
    </service> 
</services> 

答えて

3

キーがposition()機能です。これは、両方の<xsl:for-each>で動作します:

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

    <xsl:output indent="yes"/> 

    <xsl:template match="/reference"> 
    <services> 
     <xsl:for-each select="*[starts-with(local-name(), 'ref_name_')][. != '']"> 
     <xsl:variable name="originalNumber" select="substring-after(local-name(), 'ref_name_')"/> 

     <service name="reference" id="{position()}"> 
      <name> 
      <xsl:value-of select="."/> 
      </name> 
      <company> 
      <xsl:value-of select="following-sibling::*[local-name()=concat('ref_company_', $originalNumber)][1]"/> 
      </company> 
      <position> 
      <xsl:value-of select="following-sibling::*[local-name()=concat('ref_position_', $originalNumber)][1]"/> 
      </position> 
     </service> 
     </xsl:for-each> 
    </services> 
    </xsl:template> 

</xsl:stylesheet> 

だけでなく<xsl:apply-tempaltes>と:

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

    <xsl:output indent="yes"/> 

    <xsl:template match="/reference"> 
    <services> 
     <xsl:apply-templates select="*[starts-with(local-name(), 'ref_name_')][. != '']"/> 
    </services> 
    </xsl:template> 


    <xsl:template match="*[starts-with(local-name(), 'ref_name_')][. != '']"> 
    <xsl:variable name="originalNumber" select="substring-after(local-name(), 'ref_name_')"/> 

    <service name="reference" id="{position()}"> 
     <name> 
     <xsl:value-of select="."/> 
     </name> 
     <company> 
     <xsl:value-of select="following-sibling::*[local-name()=concat('ref_company_', $originalNumber)][1]"/> 
     </company> 
     <position> 
     <xsl:value-of select="following-sibling::*[local-name()=concat('ref_position_', $originalNumber)][1]"/> 
     </position> 
    </service> </xsl:template> 

</xsl:stylesheet> 
+0

Thomasさん、ありがとうございます。期待どおりに動作しています。 –

1

xsl:numberがここfor-each-group group-starting-withと一緒に使用し、もあります:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:output indent="yes"/> 

    <xsl:template match="reference"> 
     <services> 
      <xsl:for-each-group select="*" group-starting-with="*[starts-with(local-name(), 'ref_name_')]"> 
       <xsl:if test="normalize-space()"> 
        <service name="reference"> 
         <xsl:attribute name="id"> 
          <xsl:number count="*[starts-with(local-name(), 'ref_name_') and normalize-space()]"/> 
         </xsl:attribute> 
         <xsl:apply-templates select="current-group()"/> 
        </service> 
       </xsl:if> 
      </xsl:for-each-group> 
     </services> 
    </xsl:template> 

    <xsl:template match="reference/*"> 
     <xsl:element name="{replace(local-name(), '^ref_|_[0-9]+$', '')}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:template> 

</xsl:transform> 

オンラインhttp://xsltransform.net/ncdD7nmで。

関連する問題