XSLT Transformation根据条件获取元素并将其映射到兄弟

时间:2017-07-06 15:10:47

标签: xml xslt xslt-1.0

我需要使用以下规则转换xml。我坚持转型。

规则如下:

对于ns1的每个匹配:Account / ns3:Policies / ns3:Policy / ns3:PolicyConditions / ns3:PolicyCondition / ns3:PolicyConditionCriteria / ns3:与ns1匹配的值:Account / ns3:Locations / ns3:Name.I需要获取ns1的值:Account / ns3:Policies / ns3:Policy / ns3:PolicyConditions / ns3:PolicyCondition / ns2:ItemData并创建新标记并将其映射到ns1:Account / ns3:Locations / ns3:LocationConditions / ns3 :LocationCondition / ns2:ConditionId和hardcode ns1:Account / ns3:Locations / ns3:LocationConditions / ns3:LocationCondition / ns2:ConditionId to 0

附加样本输入和预期输出

输入XML:

<ns1:Account xmlns:ns1="API.ExposureWorkflow">
   <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
   <ns3:Locations xmlns:ns3="API.Objects.Exposure">
      <ns3:Location>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:Name>LOC1-BU1</ns3:Name>
      </ns3:Location>
      <ns3:Location>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:Name>LOC2-BU1</ns3:Name>
      </ns3:Location>
      <ns3:Location>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:Name>LOC2-BU3</ns3:Name>
      </ns3:Location>
   </ns3:Locations>
   <ns3:Policies xmlns:ns3="API.Objects.Exposure">
      <ns3:Policy>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:PolicyConditions>
            <ns3:PolicyCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns3:PolicyConditionCriterias/>
            </ns3:PolicyCondition>
            <ns3:PolicyCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ItemData xmlns:ns2="API.Objects">28</ns2:ItemData>
               <ns3:Name>EQ Blanket28</ns3:Name>
               <ns3:PolicyConditionCriterias>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC1-BU1</ns3:Value>
                  </ns3:PolicyConditionCriteria>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC2-BU1</ns3:Value>
                  </ns3:PolicyConditionCriteria>
               </ns3:PolicyConditionCriterias>
            </ns3:PolicyCondition>
            <ns3:PolicyCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ItemData xmlns:ns2="API.Objects">29</ns2:ItemData>
               <ns3:Name>EQ Blanket29</ns3:Name>
               <ns3:PolicyConditionCriterias>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC1-BU1</ns3:Value>
                  </ns3:PolicyConditionCriteria>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC2-BU3</ns3:Value>
                  </ns3:PolicyConditionCriteria>
               </ns3:PolicyConditionCriterias>
            </ns3:PolicyCondition>
         </ns3:PolicyConditions>
      </ns3:Policy>
   </ns3:Policies>
</ns1:Account>

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:ns1="API.ExposureWorkflow" xmlns:ns2="API.Objects" xmlns:ns3="API.Objects.Exposure">
                <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>



                <!-- template to copy elements -->
                <xsl:template match="*">
                                <xsl:element name="{name()}">
                                                <xsl:apply-templates select="@* | node()"/>
                                </xsl:element>
                </xsl:template>
                <!-- template to copy attributes -->
                <xsl:template match="@*">
                                <xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>
                </xsl:template>
                <!-- template to copy the rest of the nodes -->
                <xsl:template match="comment() | text() | processing-instruction()">
                                <xsl:copy/>
                </xsl:template>
</xsl:stylesheet>

预期的输出:

<ns1:Account xmlns:ns1="API.ExposureWorkflow">
   <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
   <ns3:Locations xmlns:ns3="API.Objects.Exposure">
      <ns3:Location>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:Name>LOC1-BU1</ns3:Name>
          <ns3:LocationConditions>
            <ns3:LocationCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ConditionId xmlns:ns2="API.Objects">28</ns2:ConditionId>
            </ns3:LocationCondition>
            <ns3:LocationCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ConditionId xmlns:ns2="API.Objects">29</ns2:ConditionId>
            </ns3:LocationCondition>
      </ns3:LocationConditions>
      </ns3:Location>
      <ns3:Location>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:Name>LOC2-BU1</ns3:Name>
         <ns3:LocationConditions>
            <ns3:LocationCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ConditionId xmlns:ns2="API.Objects">28</ns2:ConditionId>
            </ns3:LocationCondition>
      </ns3:LocationConditions>
      </ns3:Location>
      <ns3:Location>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:Name>LOC2-BU3</ns3:Name>
         <ns3:LocationConditions>
            <ns3:LocationCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ConditionId xmlns:ns2="API.Objects">29</ns2:ConditionId>
            </ns3:LocationCondition>
      </ns3:LocationConditions>
      </ns3:Location>
   </ns3:Locations>
   <ns3:Policies xmlns:ns3="API.Objects.Exposure">
      <ns3:Policy>
         <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
         <ns3:PolicyConditions>
            <ns3:PolicyCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns3:PolicyConditionCriterias/>
            </ns3:PolicyCondition>
            <ns3:PolicyCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ItemData xmlns:ns2="API.Objects">28</ns2:ItemData>
               <ns3:Name>EQ Blanket28</ns3:Name>
               <ns3:PolicyConditionCriterias>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC1-BU1</ns3:Value>
                  </ns3:PolicyConditionCriteria>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC2-BU1</ns3:Value>
                  </ns3:PolicyConditionCriteria>
               </ns3:PolicyConditionCriterias>
            </ns3:PolicyCondition>
            <ns3:PolicyCondition>
               <ns2:Id xmlns:ns2="API.Objects">0</ns2:Id>
               <ns2:ItemData xmlns:ns2="API.Objects">29</ns2:ItemData>
               <ns3:Name>EQ Blanket29</ns3:Name>
               <ns3:PolicyConditionCriterias>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC1-BU1</ns3:Value>
                  </ns3:PolicyConditionCriteria>
                  <ns3:PolicyConditionCriteria>
                     <ns3:Value>LOC2-BU3</ns3:Value>
                  </ns3:PolicyConditionCriteria>
               </ns3:PolicyConditionCriterias>
            </ns3:PolicyCondition>
         </ns3:PolicyConditions>
      </ns3:Policy>
   </ns3:Policies>
</ns1:Account>

1 个答案:

答案 0 :(得分:0)

我设法翻译了xml,只是在考虑是否有更好的简单方法来实现。

                

    <xsl:for-each select="ns3:Location">
        <xsl:variable name="locationName">
            <xsl:value-of select="ns3:Name" />
        </xsl:variable>
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
            <ns3:LocConditions>
                <xsl:for-each select="//ns3:PolicyConditions/ns3:PolicyCondition">
                    <xsl:for-each
                        select="ns3:PolicyConditionCriterias/ns3:PolicyConditionCriteria">
                        <xsl:if test="ns3:Value=$locationName">
                            <!--Zero or more repetitions: -->
                            <ns3:LocCondition>
                                <ns2:Id>0</ns2:Id>

                                <ns2:ConditionId>
                                    <xsl:value-of select="../../ns2:ItemData" />

                                </ns2:ConditionId>
                            </ns3:LocCondition>
                        </xsl:if>
                    </xsl:for-each>
                </xsl:for-each>
            </ns3:LocConditions>
        </xsl:copy>
    </xsl:for-each>

</xsl:template>



            <!-- template to copy elements -->
            <xsl:template match="*">
                            <xsl:element name="{name()}">
                                            <xsl:apply-templates select="@* | node()"/>
                            </xsl:element>
            </xsl:template>
            <!-- template to copy attributes -->
            <xsl:template match="@*">
                            <xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>
            </xsl:template>
            <!-- template to copy the rest of the nodes -->
            <xsl:template match="comment() | text() | processing-instruction()">
                            <xsl:copy/>
            </xsl:template>