0

さて、元の投稿を編集しています。元の XML の名前タグを置き換えることで、少し試してみたと思います。とにかく、元のファイルからの抜粋は次のとおりです。

<EMPLOYEE_LIST>
   <EMPLOYEES>
      <EMPLOYEE>
         <EMPID>650000</EMPID>
         <FIRST_NAME>KEITH</FIRST_NAME>
         <MIDDLE_NAME>HUTCHINSON</MIDDLE_NAME>
         <LAST_NAME>ROGERS</LAST_NAME>
         <EMP_TYPE></EMP_TYPE>
         <EMP_REF_ID>500000</EMP_REF_ID>
         <JOINED_ON>2001-10-06</JOINED_ON>
         <COMMENTS>Miscellanous Comments</COMMENTS>
         <NATIONALITY>
            <VALUE>American</VALUE>
         </NATIONALITY>
         <EMP_AKA>
            <AKA_NAME>Danny</AKA_NAME>
         </EMP_AKA>
         <EMP_AKA>
            <AKA_NAME>Dan</AKANAME>
         </EMP_AKA>
         <EMP_AKA>
            <AKA_NAME>Ray</AKA_NAME>
         </EMP_AKA>
         <EMP_ADDR>
            <STREET> </STREET>
            <CITY> </CITY>
            <STATE> </STATE>
            <ZIP> </ZIP>
            <COUNTRY> </COUNTRY>
       </EMPLOYEE>
    </EMPLOYEES>
</EMPLOYEE_LIST>

上記の XML で直面している問題は、複数の AKA (別名) 属性を 1 つのプロパティに適合させる方法が見つからないことです。この変換に使用している XSL は次のとおりです。

<?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" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
        <xsl:template match="/EMPLOYEE_LIST">
            <employees>
                <xsl:apply-templates select="EMPLOYEES/node()"/>
            </employees>        
        </xsl:template>

        <xsl:template match="EMPLOYEE">
        <employee>
            <xsl:apply-templates select="*"/>
        </employee>
        </xsl:template>

        xsl:template match="EMPLOYEE/EMPID">
        <emp_id>
            <xsl:value-of select="."/>
        </emp_id>
        </xsl:template>

            <xsl:template match="EMPLOYEE/FIRST_NAME">
        <f_name>
            <xsl:value-of select="."/>
        </f_name>
        </xsl:template>

        <xsl:template match="EMPLOYEE/MIDDLE_NAME">
            <m_name>
                <xsl:value-of select="."/>
            </m_name>
        </xsl:template>

        <xsl:template match="EMPLOYEE/LAST_NAME">
            <l_name>
                <xsl:value-of select="."/>
            </l_name>
        </xsl:template>
        .
        .
        .
        .
        .
        <xsl:template match="EMPLOYEE/EMP_AKA">
        <aka_list>
            <xsl:for-each select="AKA_NAME">
                <aka>
                    <xsl:for-each select=".">
                        <xsl:apply-templates/>
                    </xsl:for-each>
                </aka>
            </xsl:for-each>
        </aka_list>
     </xsl:template>
</xsl:stylesheet>

上記の XSL を XML に適用すると、次の出力が得られます。

<?xml version="1.0" encoding="UTF-8"?>
<employees>
      <employee>
         <emp_id>111345</emp_id>
         <f_name>KEITH</f_name>
         <m_name>HUTCHINSON</m_name>
         <l_name>ROGERS</l_name>
         <aka_list>
            <aka>Danny</aka>
         </aka_list>
         <aka_list>
            <aka>Dan</aka>
         </aka_list>
         <aka_list>
            <aka>Ray</aka>
         </aka_list>
      </employee>
</employees>

次の形式のデータが必要なため、これは私が達成しようとしているものではありません。

<?xml version="1.0" encoding="UTF-8"?>
<employees>
      <employee>
         <emp_id>111345</emp_id>
         <f_name>KEITH</f_name>
         <m_name>HUTCHINSON</m_name>
         <l_name>ROGERS</l_name>
         <aka_list>
            <aka>Danny</aka>
            <aka>Dan</aka>
            <aka>Ray</aka>
         </aka_list>
      </employee>
</employees

これを達成する方法はありますか?

XML 内には、AKA_NAME などの膨大な数の要素があります。

         <aka_list>
            <aka>Danny</aka>
         </aka_list>
         <aka_list>
            <aka>Dan</aka>
         </aka_list>
         <aka_list>
            <aka>Ray</aka>
         </aka_list>
         <aka_list>
            <aka>Danny_2</aka>
         </aka_list>
         <aka_list>
            <aka>Dan_2</aka>
         </aka_list>
         <aka_list>
            <aka>Ray_2</aka>
         </aka_list>

変換は上位 5 つだけを繰り越し、6 番目のものは次のように切り捨てます。

         <aka_list>
            <aka>Danny</aka>
            <aka>Dan</aka>
            <aka>Ray</aka>
            <aka>Danny_2</aka>
            <aka>Dan_2</aka>
         </aka_list>
4

2 に答える 2

2

更新:完全なXMLのソリューション。

XSLTテンプレート内のコメントを使用してソリューションを説明しようとしました。

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

    <!-- Ignore text nodes by default -->
    <xsl:template match="text()" />

    <!-- Transform tag name EMPLOYEES to employees -->
    <xsl:template match="EMPLOYEES">
        <employees>
            <xsl:apply-templates select="*" />
        </employees>
    </xsl:template>

    <!-- Transform tag name EMPLOYEE to employee -->
    <xsl:template match="EMPLOYEE">
        <employee>
            <xsl:apply-templates select="*" />
        </employee>
    </xsl:template>

    <!-- Transform tag name EMPID to emp_id -->
    <xsl:template match="EMPID">
        <emp_id>
            <xsl:value-of select="." />
        </emp_id>
    </xsl:template>

    <!-- Transform tag name FIRST_NAME to f_name -->
    <xsl:template match="FIRST_NAME">
        <f_name>
            <xsl:value-of select="." />
        </f_name>
    </xsl:template>

    <!-- Transform tag name MIDDLE_NAME to m_name -->
    <xsl:template match="MIDDLE_NAME">
        <m_name>
            <xsl:value-of select="." />
        </m_name>
    </xsl:template>

    <!-- Transform tag name LAST_NAME to l_name -->
    <xsl:template match="LAST_NAME">
        <l_name>
            <xsl:value-of select="." />
        </l_name>
    </xsl:template>

    <!-- When encounter the first EMP_AKA element, print itself and its following
         siblings with the same name within an aka_list element -->
    <xsl:template match="EMP_AKA[1]">
        <aka_list>
            <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA/AKA_NAME" mode="print"/>
        </aka_list>
    </xsl:template>

    <!-- Transform tag name EMP_AKA to aka -->
    <xsl:template match="AKA_NAME" mode="print">
        <aka>
            <xsl:value-of select="." />
        </aka>  
    </xsl:template>

</xsl:stylesheet>

更新2:AKA_NAMEが他の場所で照合され、同じ方法で処理されるためにテンプレートモードを使用したくない場合は、最後の2つのテンプレートを次のテンプレートに置き換えることができます。

<!-- When encounter the first EMP_AKA element, print itself and its following
     siblings with the same name within an aka_list element -->
<xsl:template match="EMP_AKA[1]">
    <aka_list>
        <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA/AKA_NAME" />
    </aka_list>
</xsl:template>

<!-- Exclude all EMP_AKA elements (except the first one because
     the previous template has higher precedence than this one) -->
<xsl:template match="EMP_AKA" />

<!-- Transform tag name EMP_AKA to aka -->
<xsl:template match="AKA_NAME">
    <aka>
        <xsl:value-of select="." />
    </aka>  
</xsl:template>

<xsl:template match="EMP_AKA" />

このコードは、前のコードと同じ出力を生成します。


更新3:OPは、出力されるAKA_NAME要素の数を制限する方法について質問しました。これは、UPDATE2に基づくソリューションです。UPDATE2の最後のテンプレートを次のように置き換えるだけです。

<xsl:template match="EMP_AKA[1]">
    <aka_list>
        <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA[position() &lt; 5]/AKA_NAME" />
    </aka_list>
</xsl:template>

<!-- Transform tag name EMP_AKA to aka -->
<xsl:template match="AKA_NAME">
    <aka>
        <xsl:value-of select="." />
    </aka>  
</xsl:template>

<xsl:template match="EMP_AKA" />

元の回答

OPは投稿を編集し、XMLファイルを完全に変更しました。以下は私の以前の答えでした(それを削除するのは正しくないようでした)。

すべての<AKA>要素を<AKA_LIST>要素にグループ化しようとしている場合(投稿した出力が変換と一致しないため、明確ではありません)、次の変換を使用できます。

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

    <!-- Just for demo -->
    <xsl:template match="text()" />

    <!-- Match PERSON: create the list -->
    <xsl:template match="PERSON">
        <AKA_LIST>
            <xsl:apply-templates select="NAME/AKA" />
        </AKA_LIST>
    </xsl:template> 

    <!-- Outputs the AKA element, changing the tag name -->
    <xsl:template match="AKA">
        <aka>
            <xsl:value-of select="." />
        </aka>
    </xsl:template>

</xsl:stylesheet>

ソースXMLを次のように変換します。

<AKA_LIST>
   <aka>ROSE PETAL</aka>
   <aka>JOHN FILTER</aka>
</AKA_LIST>
于 2013-02-26T11:14:26.957 に答える
1

のようなタグがいくつかあるため、XSLT コードは実際には混乱します<AKA_LIST>。そこで、入力および出力の XML サンプルを使用します。これが XSLT コードです。

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

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

  <xsl:template match="PERSON">
    <xsl:copy>
      <xsl:apply-templates select="NAME[1]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="NAME">
    <xsl:copy>
      <xsl:apply-templates select="/PEOPLE/PERSON/NAME/AKA"/>
    </xsl:copy>
  </xsl:template>


</xsl:stylesheet>

入力 XML:

<?xml version="1.0" encoding="utf-8"?>
<PEOPLE>
  <PERSON>
    <NAME>
      <REFERENCE>GOOD</REFERENCE>
      <AKA>ROSE PETAL</AKA>
      </NAME>
    <NAME>
      <REFERENCE>GOOD</REFERENCE>
      <AKA>JOHN FILTER</AKA>
      </NAME>
  </PERSON>
</PEOPLE>

出力:

<?xml version="1.0" encoding="utf-8"?>
<PEOPLE>
  <PERSON>
    <NAME>
      <AKA>ROSE PETAL</AKA>
      <AKA>JOHN FILTER</AKA>
    </NAME>
  </PERSON>
</PEOPLE>

説明:

<xsl:template match="@*|node()"> ......

上記のコードは、入力から出力にタグをそのままコピーします*、他のテンプレートの一致はこれをオーバーライドします..

<xsl:template match="PERSON"> ......

<NAME>上記のコードは、 1 つのタグ (最初の)のみを出力にコピーします。

<xsl:template match="NAME">
    <xsl:copy>
      <xsl:apply-templates select="/PEOPLE/PERSON/NAME/AKA"/>
      ......

上記のコードは、 の下にあるすべてのタグをコピーし ます。タグを1 つだけコピーしているため、すべてのタグが下に表示されます。<AKA> <NAME><NAME><AKA><NAME>

于 2013-02-26T12:17:08.643 に答える