変数の使用を最小限に抑えて xslt を再構築したいと考えています。どうすれば達成できますか?現在、上位の親ノード「Books」からの属性「Add」および「Update」は、ターゲット xml でセグメント「」を構築するための条件を形成します。また、正しいコンテキストを取得するために、必要なセグメント「Drama」に変数が定義され、その属性を持つ正しいドラマ ノードが選択されます。'Add' と 'Update' とは別に、'Delete' や 'PartialUpdate' などがある場合は、コンテキストを維持するためにさらに多くの変数を定義する必要があります... 100 を超える変数は管理できません。 ..また、XSLT がページに実行されています... call-template、param、key、またはその他のグループ化メカニズムを使用して、XSLT を簡単に使用して必要な xml 結果を取得するにはどうすればよいですか。
以下は、サンプルの入力 xml です。
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Library>
<Books Id="A" Location="UK" Action="Add">
<Section>
<Drama Id="A1" Name="Short Play" Location="UK" Action="Update">
<Values>
<Value Id="A1" Location="UK" Action="Update">ABC</Value>
</Values>
</Drama>
<Drama Id="A2" Name="Source Info" Location="UK" Action="Update">
<Values>
<Value Id="A2" Location="UK" Action="Update">DEF</Value>
</Values>
</Drama>
<Drama Id="A3" Name="MFG Name" Location="UK" Action="Update">
<Values>
<Value Id="A3" Location="UK" Action="Update">E and G</Value>
</Values>
</Drama>
<Drama Id="A4" Name="Book Material Group" Location="UK" Action="Update">
<Values>
<Value Id="A4" Location="UK" Action="Update">0080</Value>
</Values>
</Drama>
<Drama Id="A5" Name="Book Number" Location="UK" Action="Update">
<Values>
<Value Id="A5" Location="UK" Action="Update">121212</Value>
</Values>
</Drama>
<Drama Id="A6" Name="Book Material Description" Location="UK" Action="Update">
<Values>
<Value Id="A6" Location="UK" Action="Update">Hard Page</Value>
</Values>
</Drama>
<Drama Id="A7" Name="Industry Sector" Location="UK" Action="Update">
<Values>
<Value Id="A7" Location="UK" Action="Update">Printing</Value>
</Values>
</Drama>
<Drama Id="A8" Name="Book Material Text" Location="UK" Action="Update">
<Values>
<Value Id="A8" Location="UK" Action="Update">Plastic coated</Value>
</Values>
</Drama>
<Drama Id="A9" Name="Book Material Type" Location="UK" Action="Update">
<Values>
<Value Id="A9" Location="UK" Action="Update">INVT</Value>
</Values>
</Drama>
<Drama Id="A10" Name="Delete Indicator" Location="UK" Action="Update">
<Values>
<Value Id="A10" Location="UK" Action="Update">Blank</Value>
</Values>
</Drama>
<Drama Id="A11" Name="UOM" Location="UK" Action="Update">
<Values>
<Value Id="A11" Location="UK" Action="Update">M</Value>
</Values>
</Drama>
</Section>
</Books>
</Library>
</Data>
多くの変数を使用して開発した XSLT を以下に示します。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<LIBRARY_DATA>
<DATA_LIST>
<!--Assign variables with values from Books segment to use under child nodes-->
<xsl:for-each select="Data/Library/Books">
<xsl:if test="@Action = 'Add'">
<xsl:variable name="vBooksAction"><xsl:value-of select="'Create_001'"/></xsl:variable>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<xsl:variable name="vBooksAction"><xsl:value-of select="'Update_002'"/></xsl:variable>
</xsl:if>
<xsl:for-each select="Section/Drama">
<xsl:if test="@Name = 'Short Play'">
<xsl:variable name="vShortPlay"><xsl:value-of select="Values/Value"/></xsl:variable>
<xsl:if test="@Action = 'Add'">
<xsl:variable name="vShortPlayAction"><xsl:value-of select="'Create_001'"/></xsl:variable>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<xsl:variable name="vShortPlayAction"><xsl:value-of select="'Update_002'"/></xsl:variable>
</xsl:if>
</xsl:if>
<xsl:if test="@Name = 'Book Material'">
<xsl:variable name="vBookMtl"><xsl:value-of select="Values/Value"/></xsl:variable>
<xsl:if test="@Action = 'Add'">
<xsl:variable name="vBookMtlAction"><xsl:value-of select="'Create_001'"/></xsl:variable>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<xsl:variable name="vBookMtlAction"><xsl:value-of select="'Update_002'"/></xsl:variable>
</xsl:if>
</xsl:if>
<xsl:if test="@Name = 'Delete Indicator'">
<xsl:variable name="vDeleteIndicator"><xsl:value-of select="Values/Value"/></xsl:variable>
</xsl:if>
<xsl:if test="@Name = 'Book Number'">
<xsl:variable name="vBookNumber"><xsl:value-of select="Values/Value"/></xsl:variable>
<xsl:if test="@Action = 'Add'">
<xsl:variable name="vBookNumberAction"><xsl:value-of select="'Create_001'"/></xsl:variable>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<xsl:variable name="vBookNumberAction"><xsl:value-of select="'Update_002'"/></xsl:variable>
</xsl:if>
</xsl:if>
<xsl:if test="@Name = 'Book Material Description'">
<xsl:variable name="vBookMtlDesc"><xsl:value-of select="Values/Value"/></xsl:variable>
<xsl:if test="@Action = 'Add'">
<xsl:variable name="vBookMtlDescAction"><xsl:value-of select="'Create_001'"/></xsl:variable>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<xsl:variable name="vBookMtlDescAction"><xsl:value-of select="'Update_002'"/></xsl:variable>
</xsl:if>
</xsl:if>
</xsl:for-each>
<!-- Constructing the segments with its field based on variable value-->
<BOOK_MATERIAL>
<xsl:if test="$vBooksAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="$vBooksAction = 'Update_002'">
<xsl:if test="$vDeleteIndicator = 'Blank'">
<xsl:if test="@Action = 'Add'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<DATA_ACTION>Update_002</DATA_ACTION>
</xsl:if>
</xsl:if>
<xsl:if test="$vDeleteIndicator != 'Blank'">
<DATA_ACTION>Delete_003</DATA_ACTION>
</xsl:if>
</xsl:if>
<FONT>Calibri</FONT>
<xsl:for-each select="Section/Drama">
<xsl:if test="@Name = 'Book Number'">
<BOOK_NUMBER><xsl:value-of select="Values/Value"/></BOOK_NUMBER>
</xsl:if>
<xsl:if test="@Name = 'Delete Indicator'">
<xsl:for-each select="Values/Value">
<xsl:if test="self::node()[text()='Blank']">
<ASSIGN>Delete</ASSIGN>
</xsl:if>
</xsl:for-each>
</xsl:if>
<xsl:if test="@Name = 'Book Material Type' and @Location='UK'">
<xsl:if test="$vBooksAction = 'Update_002'">
<MATERIAL_TYPE>Default</MATERIAL_TYPE>
</xsl:if>
<xsl:if test="$vBooksAction = 'Create_001'">
<MATERIAL_TYPE><xsl:value-of select="Values/Value"/></MATERIAL_TYPE>
</xsl:if>
</xsl:if>
<xsl:if test="@Name = 'Book Making Sector'">
<BM_SECTOR><xsl:value-of select="Values/Value"/></BM_SECTOR>
</xsl:if>
<xsl:if test="@Name = 'Book Material Group' and @Location='UK'">
<xsl:if test="$vBooksAction = 'Update_002'">
<BM_GROUP>Default</BM_GROUP>
</xsl:if>
<xsl:if test="$vBooksAction = 'Create_001'">
<BM_GROUP><xsl:value-of select="Values/Value"/></BM_GROUP>
</xsl:if>
</xsl:if>
<xsl:if test="@Name = 'UOM'and @Location='UK'">
<xsl:if test="$vBooksAction = 'Update_002'">
<BOOK_UOM>Numbers</BOOK_UOM>
</xsl:if>
<xsl:if test="$vBooksAction = 'Create_001'">
<BOOK_UOM><xsl:value-of select="Values/Value"/></BOOK_UOM>
</xsl:if>
</xsl:if>
<xsl:if test="@Name = 'Part Number'">
<BOOK_PN><xsl:value-of select="Values/Value"/></BOOK_PN>
</xsl:if>
<xsl:if test="@Name = 'MFG Name'">
<BOOK_MFG>Default</BOOK_MFG>
</xsl:if>
</xsl:for-each>
<MTL_DETAIL>
<SPEC>Plastic</SPEC>
<LNG>EN</LNG>
<xsl:if test="$vBooksAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="$vBooksAction = 'Update_002'">
<xsl:if test="$vDeleteIndicator = 'Blank'">
<DATA_ACTION><xsl:value-of select="$vBookMtlDescAction" /></DATA_ACTION>
</xsl:if>
<xsl:if test="$vDeleteIndicator != 'Blank'">
<DATA_ACTION>Delete_003</DATA_ACTION>
</xsl:if>
</xsl:if>
<MTL_DEC><xsl:value-of select="$vBookMtlDesc" /></MTL_DEC>
</MTL_DETAIL>
<BOOK_TXT_HEADER>
<xsl:if test="$vBooksAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="$vBooksAction = 'Update_002'">
<xsl:if test="$vDeleteIndicator = 'Blank'">
<xsl:if test="$vBookNumberAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="$vBookNumberAction = 'Update_002'">
<DATA_ACTION>Update_002</DATA_ACTION>
</xsl:if>
</xsl:if>
<xsl:if test="$vDeleteIndicator != 'Blank'">
<DATA_ACTION>Delete_003</DATA_ACTION>
</xsl:if>
</xsl:if>
<TXT_TYPE>Any</TXT_TYPE>
<TXT_OBJECT>MATERIAL</TXT_OBJECT>
<TXT_NAME><xsl:value-of select="$vBookNumber" /></TXT_NAME>
<BOOK_TXT_DETAIL>
<xsl:if test="$vBooksAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="$vBooksAction = 'Update_002'">
<xsl:if test="$vDeleteIndicator = 'Blank'">
<xsl:if test="$vBookNumberAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
<xsl:if test="$vBookNumberAction = 'Update_002'">
<DATA_ACTION>Update_002</DATA_ACTION>
</xsl:if>
</xsl:if>
<xsl:if test="$vDeleteIndicator != 'Blank'">
<DATA_ACTION>Delete_003</DATA_ACTION>
</xsl:if>
</xsl:if>
<TXT_FORMAT>Bold</TXT_FORMAT>
<TXT_LINE><xsl:value-of select="$vShortPlay" /></TXT_LINE>
</BOOK_TXT_DETAIL>
</BOOK_TXT_HEADER>
</BOOK_MATERIAL>
</xsl:for-each>
</DATA_LIST>
</LIBRARY_DATA>
</xsl:template>
</xsl:stylesheet>
XSLT を適用すると、必要な出力 xml は次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<LIBRARY_DATA>
<DATA_LIST>
<BOOK_MATERIAL>
<DATA_ACTION>Create_001</DATA_ACTION>
<FONT>Calibri</FONT>
<BOOK_MFG>Default</BOOK_MFG>
<BM_GROUP>0080</BM_GROUP>
<BOOK_NUMBER>121212</BOOK_NUMBER>
<MATERIAL_TYPE>INVT</MATERIAL_TYPE>
<ASSIGN>Delete</ASSIGN>
<BOOK_UOM>M</BOOK_UOM>
<MTL_DETAIL>
<SPEC>Plastic</SPEC>
<LNG>EN</LNG>
<DATA_ACTION>Create_001</DATA_ACTION>
<MTL_DEC>Hard Page</MTL_DEC>
</MTL_DETAIL>
<BOOK_TXT_HEADER>
<DATA_ACTION>Create_001</DATA_ACTION>
<TXT_TYPE>Any</TXT_TYPE>
<TXT_OBJECT>MATERIAL</TXT_OBJECT>
<TXT_NAME>121212</TXT_NAME>
<BOOK_TXT_DETAIL>
<DATA_ACTION>Create_001</DATA_ACTION>
<TXT_FORMAT>Bold</TXT_FORMAT>
<TXT_LINE>ABC</TXT_LINE>
</BOOK_TXT_DETAIL>
</BOOK_TXT_HEADER>
</BOOK_MATERIAL>
</DATA_LIST>
</LIBRARY_DATA>
また、「削除インジケーター」が「空白」でない場合、変数を使用していても、すべてのループでリセットされないため、「Delete_003」が取得されません。
私を助けてください。
変更された完全な XSLT コードを以下に示します。ここから始めて、より複雑な要件を含めることができます。ヒントをくれた @Kevin に感謝します。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<LIBRARY_DATA>
<DATA_LIST>
<xsl:for-each select="Data/Library/Books">
<BOOK_MATERIAL>
<xsl:variable name="vBooksAction">
<xsl:if test="@Action = 'Add'">
<xsl:value-of select="'Create_001'"/>
</xsl:if>
<xsl:if test="@Action = 'Update'">
<xsl:value-of select="'Update_002'"/>
</xsl:if>
</xsl:variable>
<DATA_ACTION>
<xsl:apply-templates select="@Action">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
</DATA_ACTION>
<FONT>Calibri</FONT>
<BOOK_NUMBER>
<xsl:apply-templates select="Section/Drama[@Name = 'Book Number']"/>
</BOOK_NUMBER>
<xsl:apply-templates select="Section/Drama[@Name = 'Book Material Type' and @Location='UK']">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
<xsl:apply-templates select="Section/Drama[@Name = 'Book Making Sector']"/>
<xsl:apply-templates select="Section/Drama[@Name = 'Book Material Group' and @Location='UK']">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
<xsl:apply-templates select="Section/Drama[@Name = 'UOM' and @Location='UK']">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
<xsl:apply-templates select="Section/Drama[@Name = 'Part Number']"/>
<xsl:apply-templates select="Section/Drama[@Name = 'MFG Name']"/>
<MTL_DETAIL>
<SPEC>Plastic</SPEC>
<LNG>EN</LNG>
<xsl:apply-templates select="Section/Drama[@Name = 'Delete Indicator']">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
<xsl:apply-templates select="Section/Drama[@Name = 'Book Material Description']"/>
</MTL_DETAIL>
<BOOK_TXT_HEADER>
<DATA_ACTION>
<xsl:apply-templates select="@Action">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
</DATA_ACTION>
<TXT_TYPE>Any</TXT_TYPE>
<TXT_OBJECT>MATERIAL</TXT_OBJECT>
<TXT_NAME>
<xsl:apply-templates select="Section/Drama[@Name = 'Book Number']"/>
</TXT_NAME>
<BOOK_TXT_DETAIL>
<DATA_ACTION>
<xsl:apply-templates select="@Action">
<xsl:with-param name="vBooksAction" select="$vBooksAction"/>
</xsl:apply-templates>
</DATA_ACTION>
<TXT_FORMAT>Bold</TXT_FORMAT>
<TXT_LINE>
<xsl:apply-templates select="Section/Drama[@Name = 'Short Play']"/>
</TXT_LINE>
</BOOK_TXT_DETAIL>
</BOOK_TXT_HEADER>
</BOOK_MATERIAL>
</xsl:for-each>
</DATA_LIST>
</LIBRARY_DATA>
</xsl:template>
<xsl:template match='@Action[parent::Books]'>
<xsl:param name="vBooksAction"/>
<xsl:value-of select="$vBooksAction"/>
</xsl:template>
<xsl:template match="Drama[@Name='Book Number']">
<xsl:value-of select="Values/Value"/>
</xsl:template>
<xsl:template match="Drama[@Name = 'Book Material Type' and @Location='UK']">
<xsl:param name="vBooksAction"/>
<xsl:if test="$vBooksAction = 'Update_002'">
<MATERIAL_TYPE>Default</MATERIAL_TYPE>
</xsl:if>
<xsl:if test="$vBooksAction = 'Create_001'">
<MATERIAL_TYPE>
<xsl:value-of select="Values/Value"/>
</MATERIAL_TYPE>
</xsl:if>
</xsl:template>
<xsl:template match="Drama[@Name='Book Making Sector']">
<BM_SECTOR>
<xsl:value-of select="Values/Value"/>
</BM_SECTOR>
</xsl:template>
<xsl:template match="Drama[@Name = 'Book Material Group' and @Location='UK']">
<xsl:param name="vBooksAction"/>
<xsl:if test="$vBooksAction = 'Update_002'">
<BM_GROUP>Default</BM_GROUP>
</xsl:if>
<xsl:if test="$vBooksAction = 'Create_001'">
<BM_GROUP>
<xsl:value-of select="Values/Value"/>
</BM_GROUP>
</xsl:if>
</xsl:template>
<xsl:template match="Drama[@Name = 'UOM' and @Location='UK']">
<xsl:param name="vBooksAction"/>
<xsl:if test="$vBooksAction = 'Update_002'">
<BOOK_UOM>Numbers</BOOK_UOM>
</xsl:if>
<xsl:if test="$vBooksAction = 'Create_001'">
<BOOK_UOM>
<xsl:value-of select="Values/Value"/>
</BOOK_UOM>
</xsl:if>
</xsl:template>
<xsl:template match="Drama[@Name='Part Number']">
<BOOK_PN>
<xsl:value-of select="Values/Value"/>
</BOOK_PN>
</xsl:template>
<xsl:template match="Drama[@Name='MFG Name']">
<BOOK_MFG>
<xsl:value-of select="Values/Value"/>
</BOOK_MFG>
</xsl:template>
<xsl:template match="Drama[@Name='Delete Indicator']">
<xsl:param name="vBooksAction"/>
<xsl:choose>
<xsl:when test="$vBooksAction = 'Update_002'">
<xsl:for-each select="Values/Value">
<xsl:if test="self::node()[text()!='Blank']">
<DATA_ACTION>Delete_003</DATA_ACTION>
</xsl:if>
<xsl:if test="self::node()[text()='Blank']">
<DATA_ACTION>Update_002</DATA_ACTION>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$vBooksAction = 'Create_001'">
<DATA_ACTION>Create_001</DATA_ACTION>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Drama[@Name='Book Material Description']">
<MTL_DEC>
<xsl:value-of select="Values/Value"/>
</MTL_DEC>
</xsl:template>
<xsl:template match="Drama[@Name='Short Play']">
<xsl:value-of select="Values/Value"/>
</xsl:template>
</xsl:stylesheet>