1

XMLを使用し、それに複数の条件を適用する際にいくつかの問題が発生しています。次のような入力XMLがあります。

<?xml version="1.0" encoding="UTF-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType">
    <result>
        <resultSets>
            <resultSet>
                <row>
                    <column1>11111</column1>
                    <column2>0</column2>
                    <column3>imageId/111111</column3>
                    <column4>2012-04-03T10:11:22.187</column4>
                </row>
                <row>
                    <column1>11111</column1>
                    <column2>2</column2>
                    <column3>imageId/111112</column3>
                    <column4>2012-04-03T10:11:22.187</column4>
                </row>
                <row>
                    <column1>11111</column1>
                    <column2>2</column2>
                    <column3>imageId/111113</column3>
                    <column4>2012-04-03T10:11:22.187</column4>
                </row>
                <row>
                    <column1>22222</column1>
                    <column2>0</column2>
                    <column3>imageId/222222</column3>
                    <column4>2012-04-03T10:11:22.187</column4>
                </row>
                <row>
                    <column1>22222</column1>
                    <column2>2</column2>
                    <column3>imageId/222223</column3>
                    <column4>2012-04-03T10:11:22.187</column4>
                </row>
            </resultSet>
        </resultSets>
    </result>
</results>

しかし、私はそれをこのように見せたいです:

<?xml version="1.0" encoding="UTF-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType">
    <result>
        <row>
            <id>11111</id>
            <lagrgeImage>imageId/111111</lagrgeImage>
            <smallImage>imageId/111112</smallImage>
            <smallImage>imageId/111113</smallImage>
        </row>
        <row>
            <id>22222</id>
            <lagrgeImage>imageId/222222</lagrgeImage>
            <smallImage>imageId/222223</smallImage>
        </row>
    </result>
</results>

ご覧のとおり、2つのフィルタリング条件があります。

column2 = 0の場合、出力にはlargeImageタグが必要ですが、column2 = 2の場合、出力にはsmallImageタグが必要です。

アップデート

以下の例は両方とも完全に機能しましたが、どちらもルートに予期しない名前空間が含まれています。私が得る出力は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType">
    <result>
        <row>
            <id>11111</id>
            <largeImage>imageId/111111</largeImage>
            <smallImage>imageId/111112</smallImage>
            <smallImage>imageId/111113</smallImage>
        </row>
        <row>
            <id>22222</id>
            <largeImage>imageId/222222</largeImage>
            <smallImage>imageId/222223</smallImage>
        </row>
    </result>
</results>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType"上記の出力から削除するにはどうすればよいですか?

4

3 に答える 3

1

XSLT2.0を使用している場合は、for-each-group関数を使用します。

<xsl:for-each-group select="row" group-by="column1">

コンテキストがresultSetsであるとすると、これはcolumn1の「id」によって行をグループ化します。次に、現在のグループ化キーを次のように取得できます。

<xsl:value-of select="current-grouping-key()"/>

そして、グループ内のさまざまな行を取得し、それらをlargeImageまたはsmallImageに変換するには、次のようにします。

<xsl:apply-templates select="current-group()" />

これが完全なXSLTです

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

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

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

   <xsl:template match="resultSet">
      <xsl:apply-templates select="@*"/>
      <xsl:for-each-group select="row" group-by="column1">
         <row>
            <id><xsl:value-of select="current-grouping-key()"/></id>
            <xsl:apply-templates select="current-group()" />
          </row>
      </xsl:for-each-group>
   </xsl:template>

   <xsl:template match="row[column2='0']">
      <largeImage><xsl:value-of select="column3" /></largeImage>
   </xsl:template>

   <xsl:template match="row">
      <smallImage><xsl:value-of select="column3" /></smallImage>
   </xsl:template>

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

   <xsl:template match="*">
      <xsl:element name="{local-name()}"> 
         <xsl:apply-templates select="@*|node()"/>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

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

<results xmlns="http://www.castiron.com//response">
   <result>
      <row>
         <id>11111</id>
         <largeImage>imageId/111111</largeImage>
         <smallImage>imageId/111112</smallImage>
         <smallImage>imageId/111113</smallImage>
      </row>
      <row>
         <id>22222</id>
         <largeImage>imageId/222222</largeImage>
         <smallImage>imageId/222223</smallImage>
      </row>
   </result>
</results>
于 2012-06-28T15:29:34.527 に答える
0

'largeimage'要素と'smallimage'要素を(xsl forループで)吐き出すには、次のことを試してください。

<xsl:if test="/results/result/resultSets/resultSet/row/column2='0'">
<largeImage>
<xsl:value-of select="/results/result/resultSets/resultSet/row/column3"/>
</largeImage>    
</xsl:if>
于 2012-06-28T15:10:00.963 に答える
0

XSLT 1.0では、(IMO)最も簡単な解決策は、最初にすべての一意のIDを見つけることです。これは、先行する兄弟に表示されなかったIDを探すことで実現できます(つまり、IDごとに、そのIDを含む最初の要素が見つかります)。

一意のIDを取得すると、同じIDを持つ<xsl:for-each>すべての<row>兄弟(現在の要素を含む)を上書きできます。以下のコードでは、要素を使用して、値に基づいてまたは要素<xsl:choose>をチェック<column2>して挿入しました。<largeImage><smallImage><column2>

これはあなたが探していることをします:

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

    <xsl:template match="/results">
        <results>
            <xsl:copy-of select="@*"/>
            <result>
                <xsl:apply-templates select="result"/>
            </result>
        </results>
    </xsl:template>

    <xsl:template match="/results/result/resultSets/resultSet/row">
        <xsl:if test="not(column1 = preceding-sibling::row/column1)">
            <row>
                <id><xsl:value-of select="column1"/></id>
                <xsl:for-each select="../row[column1 = current()/column1]">
                    <xsl:choose>
                        <xsl:when test="column2 = '0'">
                            <largeImage><xsl:value-of select="column3"/></largeImage>
                        </xsl:when>
                        <xsl:when test="column2 = '2'">
                            <smallImage><xsl:value-of select="column3"/></smallImage>
                        </xsl:when>
                    </xsl:choose>
                </xsl:for-each>
            </row>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>
于 2012-06-28T15:15:55.397 に答える