0

さまざまな階層から ID を抽出して一覧表示する必要があるという要件があります。以下は XML のサンプルです: (顔色を反映するために 3 レベルの階層を用意しました)

入力 XML:

<Wrapper>
    <A Id="A@1">
        <B Id="B#1">
            <C Id="C$1"/>
            <C Id="C$2"/>
        </B>
        <B Id="B#2">
            <C Id="C$3"/>
            <C Id="C$4"/>
        </B>
        <B Id="B#3">
            <C Id="C$5"/>
            <C Id="C$6"/>
        </B>
        <B Id="B#4>
            <C Id="C$7"/>
            <C Id="C$8"/>
        </B>
    </A>
</Wrapper>

望ましい出力:

A Ids:
A@1

B Ids:
B#1
B#2
B#3
B#4

C Ids:
C$1
C$2
C$3
C$4
C$5
C$6
C$7
C$8

入力 XSL:原理は単純です: ルート要素 "\" に遭遇し、テキストを書き込み、階層ごとに絶対 XPath とアクセス ID を提供します。コードは次のとおりです。

<?xml version ="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:variable name="linefeed" select="'&#10;'"/>  

  <xsl:template match="/">

    <!--List of A Ids-->
      <xsl:text>A Ids:</xsl:text>
      <xsl:value-of select="$linefeed"/>

      <xsl:for-each select="/Wrapper/A/@Id">
        <xsl:value-of select="concat(.,$linefeed)"/>
      </xsl:for-each>

      <xsl:value-of select="$linefeed"/>


    <!--List of B Ids-->
      <xsl:text>B Ids:</xsl:text>
      <xsl:value-of select="$linefeed"/>

      <xsl:for-each select="/Wrapper/A/B/@Id">
        <xsl:value-of select="concat(.,$linefeed)"/>
      </xsl:for-each>

      <xsl:value-of select="$linefeed"/>

    <!--List of C Ids-->
      <xsl:text>C Ids:</xsl:text>
      <xsl:value-of select="$linefeed"/>

      <xsl:for-each select="/Wrapper/A/B/C/@Id">
        <xsl:value-of select="concat(.,$linefeed)"/>
      </xsl:for-each>

      <xsl:value-of select="$linefeed"/>


  </xsl:template>
 </xsl:stylesheet>

もっと良い方法はありますか??

4

2 に答える 2

2

次の解決策は、階層内で要素が占める位置ではなく、名前で要素をグループ化することに基づいています。したがって、このソリューションは、次の場合でもsamを出力します。

  • ノードは名前でグループ化されていません。たとえば、C要素はB要素の子ではなく、A要素のルートにある可能性があります。
  • 階層内のどこかにA、B、Cとは異なるノードを追加すると(ただし、それらはWrapperの子である必要があります)、それらの@IdはXSLTスタイルシートによって自動的にリストされます。

名前を使用してノードをグループ化するのではなく、ドキュメント内のノードの位置に基づいた一般的なソリューションが必要な場合は、教えてください。ソリューションの適応を試みます。一方、これは「MuenchianGrouping」に基づく私のソリューションです

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

    <xsl:output method="text" indent="yes"/>

    <xsl:variable name="linefeed" select="'&#10;'"/>  

    <!-- Use key to group elements by local-name -->
    <xsl:key name="name-key" match="/Wrapper//*" use="local-name()"/>

    <xsl:template match="Wrapper">
        <!-- Obtain the first element for each group, where a group is
             the set of elements sharing a name -->
        <xsl:for-each select="//*[generate-id(.) = generate-id(key('name-key', local-name())[1])]">
            <!-- Print header -->
            <xsl:value-of select="concat(local-name(), ' Ids:', $linefeed)" />
            <!-- Obtain all the nodes (children of Wrapper) with the local-name of
                 the current node using the previous key -->
            <xsl:apply-templates select="key('name-key', local-name())" />
            <!-- Print line feed at the end of each different group -->
            <xsl:value-of select="$linefeed" />
        </xsl:for-each>
    </xsl:template>

    <!-- Print the information for each element -->
    <xsl:template match="*">
        <xsl:value-of select="@Id" />
        <xsl:value-of select="$linefeed" />
    </xsl:template>

</xsl:stylesheet>
于 2013-02-21T09:30:42.477 に答える
1

1つの解決策は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:variable name="linefeed" select="'&#10;'"/>

    <xsl:template match="/">
        <!--List of A Ids-->
        <xsl:text>A Ids:</xsl:text>
        <xsl:value-of select="$linefeed"/>
        <xsl:apply-templates select="//A" />

        <!--List of B Ids-->
        <xsl:text>B Ids:</xsl:text>
        <xsl:value-of select="$linefeed"/>
        <xsl:apply-templates select="//B" />

        <!--List of C Ids-->
        <xsl:text>C Ids:</xsl:text>
        <xsl:value-of select="$linefeed"/>
        <xsl:apply-templates select="//C" />
    </xsl:template>

    <xsl:template match="*">
        <xsl:value-of select="@Id" />
        <xsl:value-of select="$linefeed"/>
    </xsl:template>
</xsl:stylesheet>
于 2013-02-21T09:08:11.770 に答える