0

XSLTを使用してループを作成しようとしています。これにより、同じIDを持つすべてのアイテムが自動的にグループ化されますが、大文字と小文字は区別されません。残念ながら、私が解析しようとしているデータはクライアント駆動型であるため、ロードする前に変更することはできません。ここに関係なく、XML構造...

<Document>
    <Row>
        <Cell>ID</Cell>
    </Row>
    <Row>
        <Cell>hi</Cell>
    </Row>
    <Row>
        <Cell>Hi</Cell>
    </Row>
    <Row>
        <Cell>Hello</Cell>
    </Row>
    <Row>
        <Cell>Hello</Cell>
    </Row>
    <Row>
        <Cell>Hola</Cell>
    </Row>
</Document>

これは私が現在使用しているXSLTです...

  <xsl:template match="Document">
    <NewDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <xsl:for-each select="//Row[position() &gt; 1]/Cell[1][not(.=preceding::Row/Cell[1])]">
        <xsl:variable name="currentOrderID" select="." />
        <xsl:variable name="currentOrderGroup" select="//Row[Cell[1] = $currentOrderID]" />

        <MainID>
          <xsl:value-of select="$currentOrderGroup[1]/Cell[1]"/>
        </MainID>
        <IDs>
          <xsl:for-each select="$currentOrderGroup">
            <id>
              <xsl:value-of select="Cell[1]"/>
            </id>
          </xsl:for-each>
        </IDs>
      </xsl:for-each>
    </NewDocument>
  </xsl:template>

これは、CaSe SeNSiTiVeの方法で期待どおりに処理をまとめているだけです...すべてを大文字にするために、そこで変換を使用しようとしていますが、構文を正しく取得できないようです。

私がここで達成しようとしている結果はこれです:

<NewDocument>
  <MainID>hi</MainID>
  <IDs>
    <id>hi</id>
    <id>Hi</id>
  </IDs>  
  <MainID>Hello</MainID>
  <IDs>
    <id>Hello</id>
    <id>Hello</id>
  </IDs>
  <MainID>Hola</MainID>
  <IDs>
    <id>Hola</id>
  </IDs>
</NewDocument>

私が必要としているもののために特別に何かを見つけることができないようです。ありがとう!

4

1 に答える 1

2

XSLT1.0では、文字列を小文字に変換するには、xpathでかなり面倒な変換関数を使用する必要があります。

translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')

さらに、問題はグループ化の1つであり、XSLT1.0では、通常、MeunchianGroupingと呼ばれる手法を意味します。これを行うには、最初に、必要なグループ内のアイテムを検索するためのキーを定義します

<xsl:key 
   name="Cell" 
   match="Cell" 
   use="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>

ここでは、(小文字の)テキストコンテンツに基づいてセルを検索しています。

各グループの最初の要素を見つけるには、XMLでCell要素を探します。これは、ルックアップキーで最初に発生する要素でもあります。

<xsl:apply-templates 
   select="Row/Cell
   [generate-id() 
    = generate-id(
       key('Cell', 
         translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))[1])]"/>

次に、最初の要素を一致させると、キーを確認することでグループ内のすべての要素を一致させることができます。

これが完全なXSLTです

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="Cell" match="Cell" use="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>

   <xsl:template match="Document">
      <NewDocument>
         <xsl:apply-templates select="Row/Cell[generate-id() = generate-id(key('Cell', translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))[1])]"/>
      </NewDocument>
   </xsl:template>

   <xsl:template match="Cell">
      <MainID>
         <xsl:value-of select="."/>
      </MainID>
      <IDs>
         <xsl:apply-templates select="key('Cell', translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))" mode="group"/>
      </IDs>
   </xsl:template>

   <xsl:template match="Cell" mode="group">
      <id>
         <xsl:value-of select="."/>
      </id>
   </xsl:template>
</xsl:stylesheet>

Cell要素に一致する2つのテンプレートを区別するために、 mode属性を使用していることに注意してください。

XMLに適用すると、次のように出力されます。

<NewDocument>
   <MainID>ID</MainID>
   <IDs>
      <id>ID</id>
   </IDs>
   <MainID>hi</MainID>
   <IDs>
      <id>hi</id>
      <id>Hi</id>
   </IDs>
   <MainID>Hello</MainID>
   <IDs>
      <id>Hello</id>
      <id>Hello</id>
   </IDs>
   <MainID>Hola</MainID>
   <IDs>
      <id>Hola</id>
   </IDs>
</NewDocument>

注: IDを値として持つセルをどうするかわからなかったので、そのままにしておきました。除外する場合は、この行をXSLTに追加するだけです。

<xsl:template match="Cell[. = 'ID']" />
于 2012-04-17T21:55:18.570 に答える