2017-11-14 9 views
-1

データとカラムが同じペイロードにあるSourceからの着信JSONデータがあります。私は、次のようなXMLを生成することができたXSLTにJSONからXMLを使用して:ここXSLT - xsl:apply-templatesでの使用

<?xml version="1.0" encoding="UTF-8"?> 
<map xmlns="http://www.w3.org/2005/xpath-functions"> 
    <boolean key="allData">true</boolean> 
    <map key="factMap"> 
     <map key="T!T"> 
     <array key="rows"> 
      <map> 
       <array key="dataCells"> 
        <map> 
        <string key="label">1A</string> 
        <string key="value">1A</string> 
        </map> 
        <map> 
        <string key="label">1B</string> 
        <string key="value">1B</string> 
        </map> 
        <map> 
        <string key="label">1C</string> 
        <string key="value">1C</string> 
        </map> 
       </array> 
      </map> 
      <map> 
       <array key="dataCells"> 
        <map> 
        <string key="label">2A</string> 
        <null key="value"/> 
        </map> 
        <map> 
        <string key="label">2B</string> 
        <string key="value">2B</string> 
        </map> 
        <map> 
        <string key="label">2C</string> 
        <string key="value">2C</string> 
        </map> 
       </array> 
      </map> 
      <map> 
       <array key="dataCells"> 
        <map> 
        <string key="label">3A</string> 
        <string key="value">3A</string> 
        </map> 
        <map> 
        <string key="label">3B</string> 
        <string key="value">3B</string> 
        </map> 
        <map> 
        <string key="label">3C</string> 
        <string key="value">3C</string> 
        </map> 
       </array> 
      </map> 
     </array> 
     </map> 
    </map> 
    <map key="detailColumnInfo"> 
     <map key="Product_vod__c.F1"> 
     <string key="dataType">string</string> 
     <string key="label">F1</string> 
     </map> 
     <map key="Product_vod__c.F2"> 
     <string key="dataType">string</string> 
     <string key="label">F2</string> 
     </map> 
     <map key="Product_vod__c.F3"> 
     <string key="dataType">string</string> 
     <string key="label">F3</string> 
     </map> 
    </map> 
</map> 

各行は、ラベルと値としてdataCellsタグの下に入手可能です。 dataCellsの下の値はフィールドの値を表しますが、labelはフィールド名を表しません。フィールド名とフィールド順序は、detailColumnInfoタグの一部です。フィールド/データの順序と数は固定されていませんが、ターゲットXMLは固定されたままです。例えば。着信データは10のフィールドとデータを任意の順序で持つことができますが、ターゲットXMLは2つのフィールドしか持たないものとします。これを実装するには、実行時にF1フィールドの順序を把握し、dataCellから対応するデータを選択する必要があると私は考えています。例えば。 F1フィールドがdetailColumnInfoの最初のフィールドであれば、すべてのdataCell(1A、2A、3A)から最初の値を選択し、F1フィールドの値を持つターゲットXMLを生成しなければなりません。

Detailcolumninfoタグは列の詳細を表します。 DetailcolumninfoのValueフィールドの位置は、Datacellのフィールドの位置を決定します。クエリでポストされた入力コードの場合、F1がDetailcolumnfoの第1ラベルであれば、Datacells(1A、2A、3A)の最初の値はF1の値を表します。同様に1B、2B、3BはF2の値を表す。ターゲットXMLは次のようになります。

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Rows> 
     <Row> 
     <F1>1A</F1> 
     <F2>1B</F2> 
     <F3>1C</F3> 
     </Row> 
     <Row> 
     <F1>2A</F1> 
     <F2>2B</F2> 
     <F3>2C</F3> 
     </Row> 
     <Row> 
     <F1>3A</F1> 
     <F2>3B</F2> 
     <F3>3C</F3> 
     </Row> 
    </Rows> 
</Root> 

おかげでマーティンHonnenからXSLTを次のように、出力が達成された:私のソース・システムは、奇妙な形でヌル代表されるよう

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math fn" 
    expand-text="yes" 
    version="3.0"> 

    <xsl:param name="json-xml"> 
     <map xmlns="http://www.w3.org/2005/xpath-functions"> 
      <boolean key="allData">true</boolean> 
      <map key="factMap"> 
       <map key="T!T"> 
        <array key="rows"> 
         <map> 
          <array key="dataCells"> 
           <map> 
            <string key="label">1A</string> 
            <string key="value">1A</string> 
           </map> 
           <map> 
            <string key="label">1B</string> 
            <string key="value">1B</string> 
           </map> 
           <map> 
            <string key="label">1C</string> 
            <string key="value">1C</string> 
           </map> 
          </array> 
         </map> 
         <map> 
          <array key="dataCells"> 
           <map> 
            <string key="label">2A</string> 
            <string key="value">2A</string> 
           </map> 
           <map> 
            <string key="label">2B</string> 
            <string key="value">2B</string> 
           </map> 
           <map> 
            <string key="label">2C</string> 
            <string key="value">2C</string> 
           </map> 
          </array> 
         </map> 
         <map> 
          <array key="dataCells"> 
           <map> 
            <string key="label">3A</string> 
            <string key="value">3A</string> 
           </map> 
           <map> 
            <string key="label">3B</string> 
            <string key="value">3B</string> 
           </map> 
           <map> 
            <string key="label">3C</string> 
            <string key="value">3C</string> 
           </map> 
          </array> 
         </map> 
        </array> 
       </map> 
      </map> 
      <map key="detailColumnInfo"> 
       <map key="Product_vod__c.F1"> 
        <string key="dataType">string</string> 
        <string key="label">F1</string> 
       </map> 
       <map key="Product_vod__c.F2"> 
        <string key="dataType">string</string> 
        <string key="label">F2</string> 
       </map> 
       <map key="Product_vod__c.F3"> 
        <string key="dataType">string</string> 
        <string key="label">F3</string> 
       </map> 
      </map> 
     </map> 
    </xsl:param> 

    <xsl:variable name="label-names" as="xs:string*" select="$json-xml//fn:map[@key = 'detailColumnInfo']/fn:map/fn:string[@key = 'label']/string()"/> 

    <xsl:output indent="yes"/> 

    <xsl:template match="/" name="xsl:initial-template"> 
     <xsl:apply-templates select="$json-xml//fn:map[@key = 'factMap']"/> 
    </xsl:template> 

    <xsl:template match="fn:map[@key = 'factMap']"> 
     <Root> 
      <Rows> 
       <xsl:apply-templates select="$json-xml//fn:array[@key = 'rows']/fn:map/fn:array"/> 
      </Rows> 
     </Root> 
    </xsl:template> 

    <xsl:template match="fn:array[@key = 'rows']/fn:map/fn:array"> 
     <Row> 
      <xsl:apply-templates select="fn:map/fn:string[@key = 'value']"/>  
     </Row> 
    </xsl:template> 

    <xsl:template match="fn:string[@key = 'value']"> 
     <xsl:element name="{let $pos := position() return $label-names[$pos]}">{.}</xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

問題が発生しました。フィールドの値がヌルである場合、着信データは次のとおり

<?xml version="1.0" encoding="UTF-8"?> 
<map xmlns="http://www.w3.org/2005/xpath-functions"> 
    <boolean key="allData">true</boolean> 
    <map key="factMap"> 
     <map key="T!T"> 
     <array key="rows"> 
      <map> 
       <array key="dataCells"> 
        <map> 
        <string key="label">1A</string> 
        <string key="value">1A</string> 
        </map> 
        <map> 
        <string key="label">1B</string> 
        <string key="value">1B</string> 
        </map> 
        <map> 
        <string key="label">1C</string> 
        <string key="value">1C</string> 
        </map> 
       </array> 
      </map> 
      <map> 
       <array key="dataCells"> 
        <map> 
        <string key="label">2A</string> 
        <string key="value">2A</string> 

        </map> 
        <map> 
        <string key="label">2B</string> 
        <null key="value"/> 
        </map> 
        <map> 
        <string key="label">2C</string> 
        <string key="value">2C</string> 
        </map> 
       </array> 
      </map> 
      <map> 
       <array key="dataCells"> 
        <map> 
        <string key="label">3A</string> 
        <string key="value">3A</string> 
        </map> 
        <map> 
        <string key="label">3B</string> 
        <string key="value">3B</string> 
        </map> 
        <map> 
        <string key="label">3C</string> 
        <string key="value">3C</string> 
        </map> 
       </array> 
      </map> 
     </array> 
     </map> 
    </map> 
    <map key="detailColumnInfo"> 
     <map key="Product_vod__c.F1"> 
     <string key="dataType">string</string> 
     <string key="label">F1</string> 
     </map> 
     <map key="Product_vod__c.F2"> 
     <string key="dataType">string</string> 
     <string key="label">F2</string> 
     </map> 
     <map key="Product_vod__c.F3"> 
     <string key="dataType">string</string> 
     <string key="label">F3</string> 
     </map> 
    </map> 
</map> 

スクリプトは、次のような値をスクランブルされる:上記の例で

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Rows> 
     <Row> 
     <F1>1A</F1> 
     <F2>1B</F2> 
     <F3>1C</F3> 
     </Row> 
     <Row> 
     <F1>2A</F1> 
     <F2>2C</F2> 
     </Row> 
     <Row> 
     <F1>3A</F1> 
     <F2>3B</F2> 
     <F3>3C</F3> 
     </Row> 
    </Rows> 
</Root> 

は、F2の値がnullです。出力では、F3要素が消え、F3フィールドの値がF2フィールドの値としてジャンプします。予想される出力は次のようになります。解決策として

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Rows> 
     <Row> 
     <F1>1A</F1> 
     <F2>1B</F2> 
     <F3>1C</F3> 
     </Row> 
     <Row> 
     <F1>2A</F1> 
     <F2/> 
     <F3>2C</F3> 
     </Row> 
     <Row> 
     <F1>3A</F1> 
     <F2>3B</F2> 
     <F3>3C</F3> 
     </Row> 
    </Rows> 
</Root> 

、私は

<xsl:apply-templates select="fn:map/fn:string[@key = 'value'] | fn:map/fn:null[@key = 'value']"/>  

<xsl:apply-templates select="fn:map/fn:string[@key = 'value']"/>  

から元の文を変更しかし、これは要素が含まれていない変更することで適用され、テンプレート内のnull値を含む試してみました<null key="value"/>。 私はXSLTとXPathが新しく、これを解決するための助けが必要です。

+0

また、 ' –

+0

ありがとう、それは働いた... –

答えて

0
<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:fn="http://www.w3.org/2005/xpath-functions" 
     xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
     exclude-result-prefixes="xs math fn" 
     expand-text="yes" 
     version="3.0"> 

     <xsl:param name="json-xml"> 
      <map xmlns="http://www.w3.org/2005/xpath-functions"> 
       <boolean key="allData">true</boolean> 
       <map key="factMap"> 
        <map key="T!T"> 
         <array key="rows"> 
          <map> 
           <array key="dataCells"> 
            <map> 
             <string key="label">1A</string> 
             <string key="value">1A</string> 
            </map> 
            <map> 
             <string key="label">1B</string> 
             <string key="value">1B</string> 
            </map> 
            <map> 
             <string key="label">1C</string> 
             <string key="value">1C</string> 
            </map> 
           </array> 
          </map> 
          <map> 
           <array key="dataCells"> 
            <map> 
             <string key="label">2A</string> 
             <string key="value">2A</string> 
            </map> 
            <map> 
             <string key="label">2B</string> 
             <string key="value">2B</string> 
            </map> 
            <map> 
             <string key="label">2C</string> 
             <string key="value">2C</string> 
            </map> 
           </array> 
          </map> 
          <map> 
           <array key="dataCells"> 
            <map> 
             <string key="label">3A</string> 
             <string key="value">3A</string> 
            </map> 
            <map> 
             <string key="label">3B</string> 
             <string key="value">3B</string> 
            </map> 
            <map> 
             <string key="label">3C</string> 
             <string key="value">3C</string> 
            </map> 
           </array> 
          </map> 
         </array> 
        </map> 
       </map> 
       <map key="detailColumnInfo"> 
        <map key="Product_vod__c.F1"> 
         <string key="dataType">string</string> 
         <string key="label">F1</string> 
        </map> 
        <map key="Product_vod__c.F2"> 
         <string key="dataType">string</string> 
         <string key="label">F2</string> 
        </map> 
        <map key="Product_vod__c.F3"> 
         <string key="dataType">string</string> 
         <string key="label">F3</string> 
        </map> 
       </map> 
      </map> 
     </xsl:param> 

    <xsl:variable name="label-names" as="xs:string*" select="$json-xml//fn:map[@key = 'detailColumnInfo']/fn:map/fn:string [@key = 'label']/translate(normalize- 

space(string()),' ','')"/> 
    <xsl:output indent="yes"/>                  



    <xsl:template match="/" name="xsl:initial-template"> 
     <xsl:apply-templates select="$json-xml//fn:map[@key = 'factMap']"/> 
    </xsl:template> 

    <xsl:template match="fn:map[@key = 'factMap']"> 
     <Root> 
      <Rows> 
       <xsl:apply-templates select="$json-xml//fn:array[@key = 'rows']/fn:map/fn:array"/> 
      </Rows> 
     </Root> 
    </xsl:template> 



    <xsl:template match="fn:array[@key = 'rows']/fn:map/fn:array"> 
     <Row> 
      <xsl:apply-templates select="fn:map/fn:string[@key = 'value'] | fn:map/fn:null[@key = 'value']"/>  
     </Row> 
    </xsl:template> 

<xsl:template match="fn:string[@key = 'value'] |fn:map/fn:null[@key = 'value']"> 


     <xsl:element name="{let $pos := position() return $label-names[$pos]}">{.}</xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 
関連する問題