我正在寻找XSLT 2.0
使用group by的解决方案。我的挑战是我有一个两级XML复合体,其属性我需要用来将它与另一个节点分组并产生另一个复杂的结构。下面是实际的XML和预期的XML。我是XSLT的新手,没有取得多大进展,即使是方向也会有所帮助。
XML要转换:
<decisionTable xmlns="http:///com/tibco/cep/decision/table/model/DecisionTable.ecore">
<rule id="1">
<cond colId="1" expr="R001" id="1_1" />
<act colId="2" expr="G1" id="1_2" />
<act colId="3" expr="" id="1_3" />
<act colId="4" expr="E1.Prop1" id="1_4" />
<act colId="5" expr=">" id="1_5" />
<act colId="6" expr="E1.prop2" id="1_6" />
<act colId="7" expr="1" id="1_7" />
</rule>
<rule id="3">
<cond colId="1" expr="R001" id="3_1" />
<act colId="2" expr="G1" id="3_2" />
<act colId="3" expr="" id="3_3" />
<act colId="4" expr="E1.Prop1" id="3_4" />
<act colId="5" expr=">" id="3_5" />
<act colId="6" expr="E1.prop2" id="3_6" />
<act colId="7" expr="2" id="3_7" />
</rule>
<rule id="4">
<cond colId="1" expr="R001" id="4_1" />
<act colId="2" expr="G2" id="4_2" />
<act colId="3" expr="" id="4_3" />
<act colId="4" expr="E1.prop1" id="4_4" />
<act colId="5" expr=">" id="4_5" />
<act colId="6" expr="E1.prop2" id="4_6" />
<act colId="7" expr="1" id="4_7" />
</rule>
<rule id="6">
<cond colId="1" expr="R001" id="6_1" />
<act colId="2" expr="G2" id="6_2" />
<act colId="3" expr="" id="6_3" />
<act colId="4" expr="E1.prop1" id="6_4" />
<act colId="5" expr=">" id="6_5" />
<act colId="6" expr="E1.prop2" id="6_6" />
<act colId="7" expr="2" id="6_7" />
</rule>
<rule id="7">
<cond colId="1" expr="R002" id="7_1" />
<act colId="2" expr="G1" id="7_2" />
<act colId="3" expr="" id="7_3" />
<act colId="4" expr="E1.prop1" id="7_4" />
<act colId="5" expr=">" id="7_5" />
<act colId="6" expr="E1.prop2" id="7_6" />
<act colId="7" expr="1" id="7_7" />
</rule>
<rule id="8">
<cond colId="1" expr="R003" id="8_1" />
<act colId="2" expr="G1" id="8_2" />
<act colId="3" expr="" id="8_3" />
<act colId="4" expr="E1.prop1" id="8_4" />
<act colId="5" expr=">" id="8_5" />
<act colId="6" expr="E1.prop2" id="8_6" />
<act colId="7" expr="1" id="8_7" />
</rule>
<columns>
<column alias="RuleId" columnType="CONDITION" id="1"
name="ruleDef.RuleId" propertyPath="/Concepts/RuleDefinitionDTConcept/RuleId" />
<column alias="GroupName" columnType="ACTION" id="2"
name="ruleDef.GroupName" propertyPath="/Concepts/RuleDefinitionDTConcept/GroupName" />
<column alias="Action" columnType="ACTION" id="3" name="ruleDef.Action"
propertyPath="/Concepts/RuleDefinitionDTConcept/Action" />
<column alias="LValue" columnType="ACTION" id="4" name="ruleDef.LValue"
propertyPath="/Concepts/RuleDefinitionDTConcept/LValue" />
<column alias="Operator" columnType="ACTION" id="5"
name="ruleDef.Operator" propertyPath="/Concepts/RuleDefinitionDTConcept/Operator" />
<column alias="RValue" columnType="ACTION" id="6" name="ruleDef.RValue"
propertyPath="/Concepts/RuleDefinitionDTConcept/RValue" />
<column alias="SequenceNo" columnType="ACTION" id="7"
name="ruleDef.SequenceNo" propertyPath="/Concepts/RuleDefinitionDTConcept/SequenceNo"
propertyType="1" />
</columns>
</decisionTable>
预期产出
<?xml version="1.0" encoding="UTF-8"?>
<RuleId>
<RuleIdVal>ROO1</RuleIdVal>
<Group>
<Name>G1</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<Rvalue>E1.Prop2</Rvalue>
<Action></Action>
<Status></Status>
</EventRule>
<EventRule>
<Sequence>2</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<Rvalue>E1.Prop2</Rvalue>
<Action></Action>
<Status></Status>
</EventRule>
</Group>
<Group>
<Name>G2</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<Rvalue>E1.Prop2</Rvalue>
<Action></Action>
<Status></Status>
</EventRule>
<EventRule>
<Sequence>2</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<Rvalue>E1.Prop2</Rvalue>
<Action></Action>
<Status></Status>
</EventRule>
</Group>
</RuleId>
<RuleId>
<RuleIdVal>ROO2</RuleIdVal>
<Group>
<Name>G1</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<Rvalue>E1.Prop2</Rvalue>
<Action></Action>
<Status></Status>
</EventRule>
</Group>
</RuleId>
<RuleId>
<RuleIdVal>ROO3</RuleIdVal>
<Group>
<Name>G1</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<Rvalue>E1.Prop2</Rvalue>
<Action></Action>
<Status></Status>
</EventRule>
</Group>
</RuleId>
谢谢,
答案 0 :(得分:2)
您需要使用嵌套循环来获取输出结构。外部循环必须按RuleId
值分组,即R00X
。
<xsl:for-each-group select="dt:rule" group-by="dt:cond[@colId = '1']/@expr">
然后使用内部循环对Group Name
进行分组,即GX
<xsl:for-each-group select="current-group()" group-by="dt:act[@colId = '2']/@expr" >
最后是另一个内部循环,用于从当前组中提取<EventRule>
下的元素。
<xsl:for-each select="current-group()">
完整的XSLT如下所示
<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" />
<xsl:strip-space elements="*" />
<xsl:template match="dt:decisionTable">
<!-- outer loop to group by using rule id -->
<xsl:for-each-group select="dt:rule" group-by="dt:cond[@colId = '1']/@expr">
<RuleId>
<RuleIdVal><xsl:value-of select="current-grouping-key()" /></RuleIdVal>
<!-- inner loop to group by using group name -->
<xsl:for-each-group select="current-group()" group-by="dt:act[@colId = '2']/@expr" >
<Group>
<Name><xsl:value-of select="current-grouping-key()" /></Name>
<!-- loop to get remaining values -->
<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>
</xsl:stylesheet>
产生所需的输出
<RuleId>
<RuleIdVal>R001</RuleIdVal>
<Group>
<Name>G1</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<RValue>E1.prop2</RValue>
<Action/>
<Status/>
</EventRule>
<EventRule>
<Sequence>2</Sequence>
<LValue>E1.Prop1</LValue>
<Operator>></Operator>
<RValue>E1.prop2</RValue>
<Action/>
<Status/>
</EventRule>
</Group>
<Group>
<Name>G2</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.prop1</LValue>
<Operator>></Operator>
<RValue>E1.prop2</RValue>
<Action/>
<Status/>
</EventRule>
<EventRule>
<Sequence>2</Sequence>
<LValue>E1.prop1</LValue>
<Operator>></Operator>
<RValue>E1.prop2</RValue>
<Action/>
<Status/>
</EventRule>
</Group>
</RuleId>
<RuleId>
<RuleIdVal>R002</RuleIdVal>
<Group>
<Name>G1</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.prop1</LValue>
<Operator>></Operator>
<RValue>E1.prop2</RValue>
<Action/>
<Status/>
</EventRule>
</Group>
</RuleId>
<RuleId>
<RuleIdVal>R003</RuleIdVal>
<Group>
<Name>G1</Name>
<EventRule>
<Sequence>1</Sequence>
<LValue>E1.prop1</LValue>
<Operator>></Operator>
<RValue>E1.prop2</RValue>
<Action/>
<Status/>
</EventRule>
</Group>
</RuleId>
答案 1 :(得分:0)
在我看来,可以使用以下方式实现分组:
<xsl:stylesheet ....
xmlns:d="http:///com/tibco/cep/decision/table/model/DecisionTable.ecore"
exclude-result-prefixes="d">
<xsl:template match="d:decisionTable">
<RuleId>
<xsl:for-each-group select="d:rule" group-by="d:act[1]/expr">
<Group>
<Name><xsl:value-of select="current-grouping-key()"/></Name>
<xsl:apply-templates select="current-group()"/>
</Group>
</xsl:for-each-group>
</RuleId>
</xsl:template>
这里还有一些其他的东西,最后的“columns”元素似乎是输出中输入到列名的元数据映射列号;我不清楚它扮演的角色是什么,但它似乎是一个与分组完全不同的问题。