我想用最少的变量来重构我的 xslt。我怎样才能实现它?目前,来自更高父节点“书籍”的属性“添加”和“更新”构成了在目标 xml 中构造段“”的条件。同样为了获得正确的上下文,再次将变量定义到所需的片段“戏剧”以选择具有其属性的正确戏剧节点。现在除了“添加”和“更新”之外,如果我有“删除”、“部分更新”等……那么我必须定义更多变量来维护上下文……比如说 100 多个不可管理的变量。 ..XSLT 也正在运行到页面中...我如何使用调用模板或参数或键或其他一些分组机制来简化我的 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>