1

この質問は、以前の質問XSLT 1.0に関連しています。EXSLTを使用してサブストリングに従って要素名を取得する と、次のXMLが使用されます。

<?xml version="1.0" encoding="UTF-8"?>
<GenericRecs>
<GenericRecord>
    <record>
        <MBH1/>
    </record>
    <record>
        <BAL1/>
    </record>
    <record>
        <MBH2/>
    </record>
    <record>
        <BAL2/>
    </record>
    <record>
        <PAY2/>
    </record>
    <record>
        <MBH3/>
    </record>
    <record>
        <BAL3/>
    </record>
    <record>
        <PAY3/>
    </record>
</GenericRecord>
</GenericRecs>

そして私はこの出力を取得したいと思います:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<Card>
    <Data>MBH1</Data>
    <Data>BAL1</Data>
</Card>
<Card>
    <Data>MBH2</Data>
    <Data>BAL2</Data>
    <Data>PAY2</Data>
</Card>
<Card>
    <Data>MBH3</Data>
    <Data>BAL3</Data>
    <Data>PAY3</Data>
</Card>
</list>

Tomalakの助けを借りて、次の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" indent="yes"/>

<xsl:template match="/">
    <list>
        <xsl:apply-templates select="//record/*[starts-with(name(), 'MBH')]"/>
    </list>
</xsl:template>

<xsl:template match="//record/*[starts-with(name(), 'MBH')]">
    <Card>
        <xsl:copy/>
    </Card> 
</xsl:template>

</xsl:stylesheet>

しかし、それは私にこの出力を与えるだけです:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<Card>
    <MBH1/>
</Card>
<Card>
    <MBH2/>
</Card>
<Card>
    <MBH3/>
</Card>
</list>

<MBH>要素を一意に識別してリストするのは簡単です。一致するキーも使用しようとしました//record/*[not(starts-with(name(), 'MBH'))]が、もちろん、前のレコードに関連しない他のすべてのレコードが選択されます<MBH>。その構造で必要な出力を取得することさえ可能ですか?XSLは、次の要素に対する要素の(変化する)量をどのように知ることができ<MBH>ますか?

4

1 に答える 1

2

このXSLT1.0変換

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kByNameSuf" match="record/*"
  use="translate(name(), translate(name(),'0123456789',''),'')"/>

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

 <xsl:template match=
  "record[generate-id(*[1])
         =
          generate-id(key('kByNameSuf',
                           translate(name(*[1]),
                                     translate(name(*[1]),'0123456789',''),'')
                          )[1]
                      )
         ]
  ">
  <Card>
    <xsl:for-each select=
     "key('kByNameSuf',
          translate(name(*[1]),
                    translate(name(*[1]),'0123456789',''),'')
                    )
     ">
       <Data><xsl:value-of select="name()"/></Data>
    </xsl:for-each>
  </Card>
 </xsl:template>
 <xsl:template match="record"/>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合:

<GenericRecs>
<GenericRecord>
    <record>
        <MBH1/>
    </record>
    <record>
        <BAL1/>
    </record>
    <record>
        <MBH2/>
    </record>
    <record>
        <BAL2/>
    </record>
    <record>
        <PAY2/>
    </record>
    <record>
        <MBH3/>
    </record>
    <record>
        <BAL3/>
    </record>
    <record>
        <PAY3/>
    </record>
</GenericRecord>
</GenericRecs>

必要な正しい結果を生成します

<GenericRecs>
   <GenericRecord>
      <Card>
         <Data>MBH1</Data>
         <Data>BAL1</Data>
      </Card>
      <Card>
         <Data>MBH2</Data>
         <Data>BAL2</Data>
         <Data>PAY2</Data>
      </Card>
      <Card>
         <Data>MBH3</Data>
         <Data>BAL3</Data>
         <Data>PAY3</Data>
      </Card>
   </GenericRecord>
</GenericRecs>

説明

  1. Muenchianグループ化の使用。

  2. 名前の接尾辞にのみ数字があると想定します。

  3. 二重変換方法の使用(Michael Kayによって最初に提案されました)。


II。XSLT 2.0ソリューション

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

 <xsl:template match="GenericRecord">
     <xsl:for-each-group select="*"
        group-by="replace(name(*[1]), '^.*(\d+)$', '$1')">
      <Card>
          <xsl:for-each select="current-group()">
            <Data><xsl:value-of select="name(*[1])"/></Data>
          </xsl:for-each>
      </Card>
     </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>
于 2012-09-07T13:21:53.883 に答える