寻求XSLT 2.0分组方案:复杂XML结构转换需求
Solution for XSLT 2.0 Grouping of Decision Table XML
Hey there! Let's tackle this XML transformation problem step by step using XSLT 2.0's grouping features. First, let's break down the core logic we need to implement based on your source and target structures:
Key Grouping & Mapping Requirements
- First, group all
<rule>elements by the value of<cond colId="1">(this becomes ourRuleIdVal) - Within each RuleId group, group rules by the value of
<act colId="2">(this becomes our GroupName) - For each rule in a Group, generate an
<EventRule>by mapping values from specific<act>elements using theircolIdattributes
Complete XSLT Code
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dt="http:///com/tibco/cep/decision/table/model/DecisionTable.ecore" exclude-result-prefixes="dt"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- Match the root decisionTable element --> <xsl:template match="/dt:decisionTable"> <!-- First level grouping: group rules by RuleId (cond colId="1" expr) --> <xsl:for-each-group select="dt:rule" group-by="dt:cond[@colId='1']/@expr"> <RuleId> <RuleIdVal><xsl:value-of select="current-grouping-key()"/></RuleIdVal> <!-- Second level grouping: group current rules by GroupName (act colId="2" expr) --> <xsl:for-each-group select="current-group()" group-by="dt:act[@colId='2']/@expr"> <Group> <Name><xsl:value-of select="current-grouping-key()"/></Name> <!-- Generate EventRule for each rule in the current group --> <xsl:for-each select="current-group()"> <EventRule> <Sequence><xsl:value-of select="dt:act[@colId='7']/@expr"/></Sequence> <LValue><xsl:value-of select="dt:act[@colId='4']/@expr"/></LValue> <Operator><xsl:value-of select="dt:act[@colId='5']/@expr"/></Operator> <Rvalue><xsl:value-of select="dt:act[@colId='6']/@expr"/></Rvalue> <Action><xsl:value-of select="dt:act[@colId='3']/@expr"/></Action> <Status></Status> </EventRule> </xsl:for-each> </Group> </xsl:for-each-group> </RuleId> </xsl:for-each-group> </xsl:template> <!-- Default template to ignore unneeded nodes like <columns> --> <xsl:template match="*"/> </xsl:stylesheet>
Key Details Explained
- Namespace Handling: The source XML uses a custom namespace, so we declare it with the prefix
dtin the stylesheet. This ensures we can correctly select elements likedt:ruleanddt:condwithout missing them. - Two-Level Grouping:
- The outer
xsl:for-each-groupclusters all rules by their RuleId value (from the first condition column) - The inner
xsl:for-each-groupfurther groups rules within each RuleId set by their GroupName (from the second action column)
- The outer
- Value Mapping: For each rule in the inner group, we pull values directly from
<act>elements using theircolIdattributes to match the target XML's structure (e.g.,colId="7"maps to<Sequence>) - Clean Output: The default template
<xsl:template match="*"/>ensures non-relevant elements like<columns>from the source don't appear in the final output.
This stylesheet will generate exactly the target XML structure you requested, with proper grouping and value mapping.
内容的提问来源于stack exchange,提问作者bala
相关产品推荐
相关产品推荐

