2011-03-23 10 views
0

ソースXMLを検証し、Attributes/Attribute/Nameを探す必要があります。 Name = 'ComplexAttr'の場合は、Data/Attributes(where @Type='common')/Collection/ComplexAttrの子ノードにします。それが存在しない場合は、デフォルト値を持つノードを作成します。しかし、すべてのノードを@Type='ComplexAttr'で検証する必要がありますので、可能な限り動的にする必要があります。 ソースXMLでは、私は@Type='ComplexAttr'というノードが1つしかないことがわかります。しかし、変換されたサンプルのXMLには、<Attr>の2つのノードがあります。これは次のXSLTで行いたいものです。どうすればいいのか教えてください。 ありがとうございます。XSLT souurceが見つからない場合、デフォルト値で子ノードを確認して作成する

XSLT:

<!DOCTYPE xsl:stylesheet [<!ENTITY key "concat(Type[. != 'ComplexAttr'],substring('common',1 div (Type = 'ComplexAttr')))"> 
]> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="type" match="Attribute" use="&key;"/> 
    <xsl:template match="/"> 
     <Data Schema="XML A"> 
      <xsl:apply-templates 
       select="XML/Attributes/Attribute[ 
          generate-id() = generate-id(key('type', &key;)[1]) 
         ]"> 
       <xsl:sort select="&key;" order="descending"/> 
      </xsl:apply-templates> 
      <errorCodes> 
       <xsl:apply-templates select="XML/Attributes/Attribute" 
            mode="errors"/> 
      </errorCodes> 
     </Data> 
    </xsl:template> 
    <xsl:template match="Attribute"> 
     <xsl:variable name="vCurrent-Grouping-Key" select="&key;"/> 
     <Attributes type="{$vCurrent-Grouping-Key}"> 
      <xsl:apply-templates select="key('type',$vCurrent-Grouping-Key)" 
           mode="out"/> 
     </Attributes> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out" name="makeAttr"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute[Type='ComplexAttr']" mode="out"> 
     <Collection id="" name="test"> 
      <ComplexAttr refId="0"> 
       <MaskValue /> 
       <xsl:call-template name="makeAttr"/> 
      </ComplexAttr> 
     </Collection> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="errors"/> 
    <xsl:template match="Attribute[Value='']" mode="errors"> 
     <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode> 
    </xsl:template> 
</xsl:stylesheet> 

ソースXML:

<?xml version="1.0" encoding="windows-1252"?> 
<XML> 
    <Attributes> 
     <Attribute> 
      <id>5</id> 
      <Name>Buyer ID</Name> 
      <Type>common</Type> 
      <Value>Lee</Value> 
     </Attribute> 
     <Attribute> 
      <id>331</id> 
      <Name>Enviornment</Name> 
      <Type>common</Type> 
      <Value>Development</Value> 
     </Attribute> 
     <Attribute> 
      <id>79</id> 
      <Name>Retail</Name> 
      <Type>common</Type> 
      <Value></Value> 
     </Attribute> 
     <Attribute> 
      <id>402</id> 
      <Name>Gender</Name> 
      <Type>category</Type> 
      <Value>Men</Value> 
     </Attribute> 
    <Attribute> 
     <id>1197</id> 
     <Name>UPC</Name> 
     <Type>ComplexAttr</Type> 
     <Value>Testing</Value> 
     <Path /> 
    </Attribute> 
</Attributes> 

----変換されたXML

<Data Schema="XML A"> 
    <Attributes type="common"> 
     <Attr id="5" name="Buyer ID" value="Lee" /> 
     <Attr id="331" name="Enviornment" value="Development" /> 
     <Attr id="79" name="Retail" value="" /> 
     <Collection id="" name="test"> 
      <ComplexAttr refId="0"> 
       <MaskValue /> 
       <Attr id="1197" name="UPC" value="Testing" /> 
       <Attr id="123" name="Size" value="Test" /> 
      </ComplexAttr> 
     </Collection> 
    </Attributes> 
    <Attributes type="category"> 
     <Attr id="402" name="Gender" value="Men" /> 
    </Attributes> 
    <errorCodes> 
     <errorCode>"value for Retail is missing."</errorCode> 
    </errorCodes> 
</Data> 
+0

。フォーマットされていないものを教えてくれますか?次回は注意が必要です。 – JohnXsl

+0

確かに。主なものは、大きなコードブロックのすべての行を4つのスペースでインデントすることです。ブロックを選択し、テキストエリアの上の '{}'アイコンをクリックすることで、これを自動的に行うことができます。私はまた、文章の途中にあるコードであっても、他のコードを整形するのが好きです。これは '{}'を使っても、バックトック( 'tab'キーの上にある文字)でコードを囲むことで手作業で行うことができます。 –

+0

@Iwburk - ヒントのおかげで。私はコードをより読みやすく分かりやすくするためにあなたの提案に従います。 – JohnXsl

答えて

1

更新:もっとプッシュスタイルのアプローチとの完全なスタイルシート(それは遅、あなたが知っている...)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="type" match="Attribute" use="Type"/> 
    <xsl:template match="/"> 
     <Data Schema="XML A"> 
      <xsl:apply-templates 
       select="XML/Attributes/Attribute[ 
          generate-id() = generate-id(key('type', Type)[1]) 
         ]"> 
       <xsl:sort select="Type" order="descending"/> 
      </xsl:apply-templates> 
      <errorCodes> 
       <xsl:apply-templates select="XML/Attributes/Attribute" 
            mode="errors"/> 
      </errorCodes> 
     </Data> 
    </xsl:template> 
    <xsl:template match="Attribute"> 
     <xsl:if test="Type!='ComplexAttr'"> 
      <Attributes type="{Type}"> 
       <xsl:apply-templates select="key('type',Type)" 
            mode="out"/> 
       <xsl:if test="Type='common'"> 
        <Collection id="" name="test"> 
         <ComplexAttr refId="0"> 
          <MaskValue /> 
          <xsl:apply-templates 
           select="key('type','ComplexAttr')" 
           mode="out"/> 
         </ComplexAttr> 
        </Collection> 
       </xsl:if> 
      </Attributes> 
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute[Type='ComplexAttr']" mode="out"> 
     <Attr id="{id}" 
       name="{Name}{substring('UPC',1 div not(Name[normalize-space()]))}" 
       value="{Value}{substring('Testing',1 div not(Value[normalize-space()]))}"/> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="errors"/> 
    <xsl:template match="Attribute[Value='']" mode="errors"> 
     <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode> 
    </xsl:template> 
</xsl:stylesheet> 

出力:フォーマットへの感謝@Iwburk

<Data Schema="XML A"> 
    <Attributes type="common"> 
    <Attr id="5" name="Buyer ID" value="Lee"/> 
    <Attr id="331" name="Enviornment" value="Development"/> 
    <Attr id="79" name="Retail" value=""/> 
    <Collection id="" name="test"> 
     <ComplexAttr refId="0"> 
     <MaskValue/> 
     <Attr id="1197" name="UPC" value="Testing"/> 
     </ComplexAttr> 
    </Collection> 
    </Attributes> 
    <Attributes type="category"> 
    <Attr id="402" name="Gender" value="Men"/> 
    </Attributes> 
    <errorCodes> 
    <errorCode> 
    "value for Retail is missing." 
    </errorCode> 
    </errorCodes> 
</Data> 
+0

@Alejandro。お返事をありがとうございます。あなたは正しいことが、私がする必要があるものです。しかし、あなたが提案したように変更を加えてコードを追加した後、私は期待される出力を得ていません。 Collection要素では、私にAttrを与えていません。しかし、@ Type = 'ComplexAttr'と何度でもCollection要素を繰り返しています。 @Type = 'ComplexAttr'を何回も見つけたときに、を呼び出すように見えます。私はposition()> 0を変更しました。今コレクション要素のAttrをすべて取得しています。しかし、それはまだCollection要素を繰り返しています。 @Alejandro。 – JohnXsl

+0

@Type = ComplexAttrがソースXMLに存在しない場合、デフォルトのCollection要素を作成していません。どのように私はこれを行うことができますか? – JohnXsl

+0

@JohnXsl:アップデートを確認してください。よりプッシュスタイル。 –

関連する問題