2017-10-02 16 views
0

'条件'が空要素を正しく識別していません。目的の出力に 'EMPTYAddress2'属性が表示されます。私はいろいろな「条件」ではなく運を試みました。私は初心者を助けてください。私はOxygen XML Developerを使用していますが、エラーは返されません。条件が空の要素を識別しない場合のXSL

XMLソースファイル:

<InterfaceData> 
    <OBJECT_ACTION_ID>16283</OBJECT_ACTION_ID> 
    <Employee> 
     <Employee> 
      <EmployeeBasic> 
       <EmployeeNo>50064</EmployeeNo> 
      </EmployeeBasic> 
      <EmployeeBasic_DateMarriageCeased> 
       <PersonDetailsRecords> 
        <PersonDetails> 
         <DateMarriageCeased/> 
        </PersonDetails> 
       </PersonDetailsRecords> 
      </EmployeeBasic_DateMarriageCeased> 
      <EmployeeAddress> 
       <AddressRecords> 
        <AddressDetails> 
         <Address1>Line1</Address1> 
         <Address2/> 
         <Address3>Line3</Address3> 
         <Address4>Line4</Address4> 
         <Postcode>Postcode</Postcode> 
        </AddressDetails> 
       </AddressRecords> 
      </EmployeeAddress> 
     </Employee> 
    </Employee> 
</InterfaceData> 

XSLスタイルシート:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:template match="/"> 
     <xsl:for-each-group select="//InterfaceData" group-by="OBJECT_ACTION_ID"> 
      <!-- Employee --> 
      <EmployeeAddress> 
       <xsl:for-each select="current-group()//AddressDetails"> 
        <xsl:call-template name="CGIderiveAddress"> 
         <xsl:with-param name="myVarAddress1" select="current-group()//Address1/text()"/> 
         <xsl:with-param name="myVarAddress2" select="current-group()//Address2/text()"/> 
         <xsl:with-param name="myVarAddress3" select="current-group()//Address3/text()"/> 
         <xsl:with-param name="myVarAddress4" select="current-group()//Address4/text()"/> 
         <xsl:with-param name="myVarPostcode" select="current-group()//Postcode/text()"/> 
        </xsl:call-template> 
       </xsl:for-each> 
      </EmployeeAddress> 
     </xsl:for-each-group> 
    </xsl:template> 
    <xsl:template name="CGIderiveAddress"> 
     <xsl:param name="myVarAddress1"/> 
     <xsl:param name="myVarAddress2"/> 
     <xsl:param name="myVarAddress3"/> 
     <xsl:param name="myVarAddress4"/> 
     <xsl:param name="myVarPostcode"/> 
     <xsl:attribute name="Address1"> 
      <xsl:value-of select="$myVarAddress1"/> 
     </xsl:attribute> 
     <xsl:choose> 
      <!-- Address Line 2 is empty and Adress Line 3 exists --> 
      <xsl:when test="$myVarAddress2 = ''"> 
       <xsl:attribute name="EMPTYAddress2"> 
        <xsl:value-of select="'EMPTYAddress2'"/> 
       </xsl:attribute> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:attribute name="NotEMPTYAddress2"> 
        <xsl:value-of select="'NotEMPTYAddress2'"/> 
       </xsl:attribute> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

XSL出力:あなたがそうのようなmyVarAddress2を定義している

<?xml version="1.0" encoding="UTF-8"?> 
<EmployeeAddress Address1="Line1" 
       NotEMPTYAddress2="NotEMPTYAddress2"/> 
+1

'for-each-group 'がないときに' current-group() 'を使用することは全く意味がありません。 –

+1

'group-by'や' group-adjacent'や 'group-starting-with' /' ending-with'のない 'for-each-group'は意味がありません。グループ分けが適切でない場合は、最小限の完全なサンプルを作成する時間を取るよりも、問題を再現できるように、入力内容、得られる出力、および望む結果が反映されます。 –

+0

また、ルート要素である 'AddressRecords'に対して' for-each-group'を実行していて、それらのうちの1つだけが存在します。これはグループ化するものではありません。 –

答えて

1

は、ほぼ常に間違いです。この場合、Address2要素が存在し、子を持たない場合、Address2/text()は空のシーケンスです(文字列の長さがゼロのノードではありません)。何もない文字列と等しいかどうかを空のシーケンスでテストすると、結果は常にfalseになります。

テンプレートCGIderiveAddressはすべてのパラメータが文字列であると考えているので、xsl:param要素にas = "xs:string"を使用してそれを宣言することをお勧めします。これを行った場合は、許可されていない空のシーケンスを提供しているというエラーメッセージが表示されます。エラーメッセージは常に不正確な結果よりも優れています。そのためには、すべての変数と(特に)パラメータの型を宣言するのが良い方法です。

次に、単に<xsl:with-param select="current-group()//Address2"/>を使用してください。期待値は文字列なので、Address2要素はアトマイゼーションされ、文字列に変換されます。これは、Address2要素が空の場合は長さゼロの文字列になります。 Address2がないときにも長さゼロの文字列が必要な場合は、string(current-group()//Address2)を使用します。

より慎重にコードを見てみると、ここでは別の明白なバグがあります:

<xsl:for-each select="current-group()//AddressDetails"> 
    <xsl:call-template name="CGIderiveAddress"> 
     <xsl:with-param name="myVarAddress1" 
      select="current-group()//Address1/text()"/> 

私はすべてのAddress1値、あなたが実際にあなたが現在処理しているAddressDetailsためAddress1値を渡したいことを確認していない感じが要素の現在のグループのために。単純に

<xsl:with-param name="myVarAddress1" select="Address1"/> 
+0

華麗な、説明のおかげで。私のような初心者にも有益! – murfy92

+0

しかし、私はエラーが発生しています** XPST0081:名前空間接頭辞 'xs'は宣言されていません。 'xsl:param name = "myVarAddress1" as = "xs:string" /> ** – murfy92

+1

それから、宣言してください。Murfy ... xsl:stylesheet要素に 'xmlns:xs =" http://www.w3.org/2001/XML/Schema "'が必要です。 –

1

...

<xsl:with-param name="myVarAddress2" select="current-group()//Address2/text()"/> 

入力XMLサンプルのAddress2には子テキストノードが含まれていないため、$myVarAddress2パラメータに空のシーケンスが含まれています。空のシーケンスは空文字列と同じではないため、テスト$myVarAddress2 = ''はfalseです。代わりに

、あなたがXSLT 2.0を使用しているとして、あなたがこれを行うことが....私はInterfaceDataは、ルート要素がありません少なくともので、あなたのXSLTにグループ分けが来るかを確認することはできません

<xsl:when test="empty($myVarAddress2)"> 

注意。

また、あなたの質問に示すXSLTのために、あなたはそのようなパラメータを簡素化することができ... /text()を使用して

<xsl:with-param name="myVarAddress2" select="Address2/text()"/> 
関連する問題