我需要通过比较两个不同的xpath并从子节点获取值并转换XML来创建一个xslt。
规则如下:
1.)I need to compare the location-number inside buildings/building/building-header/location-number with buildings/policy/coverages/coverage/location-rule/insured-objects/insured-object/insured-object-nr and for the locations not matching i need to create element Policy/PolicyConditions/Name as No coverage and map the Policy/PolicyConditions/PolicyConditionCriteria/Value as the building-number ie.,LU4-B1 in my below example.
2.)for each buildings/policy/coverages/coverage check for limit/limit-type/@code is Bla and for each location-rule/insured-objects/insured-object/insured-object-nr check for location-number inside buildings/building/building-header/location-number and get the
buildings/building/building-header/building-number create Policy/PolicyConditions/Name as EQ Blanket and map the Policy/PolicyConditions/PolicyConditionCriteria/Value as the building-number LU1-B1,LU1-B1,LU2-B2
3.)for each buildings/policy/coverages/coverage check for limit/limit-type/@code is Sub and for each location-rule/insured-objects/insured-object/insured-object-nr check for location-number inside buildings/building/building-header/location-number and get the
buildings/building/building-header/building-number create Policy/PolicyConditions/Name as EQ Sublimit and map the Policy/PolicyConditions/PolicyConditionCriteria/Value as the building-number LU2-B1,LU2-B2,LU3-B1,LU3-B2
Rule 2 and 3 are more or less the same only check that is different is with the limit/limit-type/@code.
我能够实现规则2和规则3,但是无法编写逻辑来实现规则1中不匹配的xpath。
我只能使用xslt版本1.0
输入:
<buildings>
<building>
<building-header>
<location-number>LU1</location-number>
<building-number>LU1-B1</building-number>
</building-header>
</building>
<building>
<building-header>
<location-number>LU2</location-number>
<building-number>LU2-B1</building-number>
</building-header>
</building>
<building>
<building-header>
<location-number>LU2</location-number>
<building-number>LU2-B2</building-number>
</building-header>
</building>
<building>
<building-header>
<location-number>LU3</location-number>
<building-number>LU3-B1</building-number>
</building-header>
</building>
<building>
<building-header>
<location-number>LU3</location-number>
<building-number>LU3-B2</building-number>
</building-header>
</building>
<building>
<building-header>
<location-number>LU4</location-number>
<building-number>LU4-B1</building-number>
</building-header>
</building>
<policy-details>
<coverages>
<coverage>
<limit>
<limit-type code="Bla"/>
</limit>
<location-rule>
<insured-objects>
<insured-object>
<insured-object-nr>LU1</insured-object-nr>
</insured-object>
<insured-object>
<insured-object-nr>LU2</insured-object-nr>
</insured-object>
</insured-objects>
</location-rule>
</coverage>
<coverage>
<limit>
<limit-type code="Sub"/>
</limit>
<location-rule>
<insured-objects>
<insured-object>
<insured-object-nr>LU2</insured-object-nr>
</insured-object>
<insured-object>
<insured-object-nr>LU3</insured-object-nr>
</insured-object>
</insured-objects>
</location-rule>
</coverage>
</coverages>
</policy>
</buildings>
示例XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<policy>
<xsl:for-each select="//coverage">
<xsl:if test="limit/limit-type/@code='Bla'">
<PolicyConditions>
<Name>EQ Blanket</Name>
<xsl:for-each select="location-rule/insured-objects/insured-object">
<xsl:variable name="var_Ins_Obj">
<xsl:value-of select="insured-object-nr"/>
</xsl:variable>
<xsl:for-each select="//building">
<xsl:variable name="var_loc_Num">
<xsl:value-of select="building-header/location-number"/>
</xsl:variable>
<xsl:if test="$var_loc_Num=$var_Ins_Obj">
<xsl:variable name="locBuild">
<xsl:value-of select="building-header/building-number"/>
</xsl:variable>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>
<xsl:value-of select="$locBuild"/>
</Value>
</PolicyConditionCriteria>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</PolicyConditions>
</xsl:if>
<xsl:if test="limit/limit-type/@code='Sub'">
<PolicyConditions>
<Name>EQ Sublimit</Name>
<xsl:for-each select="location-rule/insured-objects/insured-object">
<xsl:variable name="var_Ins_Obj">
<xsl:value-of select="insured-object-nr"/>
</xsl:variable>
<xsl:for-each select="//building">
<xsl:variable name="var_loc_Num">
<xsl:value-of select="building-header/location-number"/>
</xsl:variable>
<xsl:if test="$var_loc_Num=$var_Ins_Obj">
<xsl:variable name="locBuild">
<xsl:value-of select="building-header/building-number"/>
</xsl:variable>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>
<xsl:value-of select="$locBuild"/>
</Value>
</PolicyConditionCriteria>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</PolicyConditions>
</xsl:if>
</xsl:for-each>
</policy>
</xsl:template>
</xsl:stylesheet>
实际输出:
<policy>
<PolicyConditions>
<Name>EQ Blanket</Name>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU1-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B2</Value>
</PolicyConditionCriteria>
</PolicyConditions>
<PolicyConditions>
<Name>EQ Sublimit</Name>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B2</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU3-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU3-B2</Value>
</PolicyConditionCriteria>
</PolicyConditions>
预期产出:
<Policy>
<PolicyConditions>
<Name>No Coverage</Name>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU4-B1</Value>
</PolicyConditionCriteria>
</PolicyConditions>
<PolicyConditions>
<Name>EQ Blanket</Name>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU1-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B2</Value>
</PolicyConditionCriteria>
</PolicyConditions>
<PolicyConditions>
<Name>EQ Sublimit</Name>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU2-B2</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU3-B1</Value>
</PolicyConditionCriteria>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>LU3-B2</Value>
</PolicyConditionCriteria>
</PolicyConditions>
</Policy>
答案 0 :(得分:0)
这是一个解决方案:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="noCoverage">
<xsl:for-each select="//building/building-header/location-number">
<xsl:variable name="locationNumber" select="text()"/>
<xsl:if test="boolean(//coverage/location-rule/insured-objects/insured-object/insured-object-nr[text()=$locationNumber]) = false">
<xsl:value-of select="'true'"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<policy>
<xsl:if test="contains($noCoverage, 'true')">
<PolicyConditions>
<Name>No Coverage</Name>
<xsl:for-each select="//building/building-header/location-number">
<xsl:variable name="locationNr" select="text()"/>
<xsl:if test="boolean(//coverage/location-rule/insured-objects/insured-object/insured-object-nr[text()=$locationNr]) = false">
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>
<xsl:value-of select="../building-number"/>
</Value>
</PolicyConditionCriteria>
</xsl:if>
</xsl:for-each>
</PolicyConditions>
</xsl:if>
<xsl:for-each select="//coverage">
<xsl:if test="limit/limit-type/@code='Bla'">
<PolicyConditions>
<Name>EQ Blanket</Name>
<xsl:for-each select="location-rule/insured-objects/insured-object">
<xsl:variable name="var_Ins_Obj">
<xsl:value-of select="insured-object-nr"/>
</xsl:variable>
<xsl:for-each select="//building">
<xsl:variable name="var_loc_Num">
<xsl:value-of select="building-header/location-number"/>
</xsl:variable>
<xsl:if test="$var_loc_Num=$var_Ins_Obj">
<xsl:variable name="locBuild">
<xsl:value-of select="building-header/building-number"/>
</xsl:variable>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>
<xsl:value-of select="$locBuild"/>
</Value>
</PolicyConditionCriteria>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</PolicyConditions>
</xsl:if>
<xsl:if test="limit/limit-type/@code='Sub'">
<PolicyConditions>
<Name>EQ Sublimit</Name>
<xsl:for-each select="location-rule/insured-objects/insured-object">
<xsl:variable name="var_Ins_Obj">
<xsl:value-of select="insured-object-nr"/>
</xsl:variable>
<xsl:for-each select="//building">
<xsl:variable name="var_loc_Num">
<xsl:value-of select="building-header/location-number"/>
</xsl:variable>
<xsl:if test="$var_loc_Num=$var_Ins_Obj">
<xsl:variable name="locBuild">
<xsl:value-of select="building-header/building-number"/>
</xsl:variable>
<PolicyConditionCriteria>
<Field>LOCNAME</Field>
<Value>
<xsl:value-of select="$locBuild"/>
</Value>
</PolicyConditionCriteria>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</PolicyConditions>
</xsl:if>
</xsl:for-each>
</policy>
</xsl:template>
</xsl:stylesheet>
基本上,我添加了一个变量,我检查是否存在没有相应的insured-object-nr的位置编号。如果有,我将变量的值添加到字符串'true'。
然后,在模板内部检查变量名称,并再次检查当前位置编号是否没有相应的insured-object-nr。