2016-12-30 39 views
1

我的XML看起來像這樣插入使用數據所選擇的節點的子元素:我需要一個XSL轉換,從一個祖先

<SCL> 
    <IED name="D60_220SW1"> 
    <AccessPoint name="S1"> 
     <Server> 
     <LDevice inst="Master"> 
      <LN0 lnClass="LLN0" inst="" lnType="LLN0_0"> 
      <ReportControl name="URCB01" rptID="XYZ" > 
       <TrgOps dchg="true" /> 
       <OptFields configRef="true" /> 
      <RptEnabled max="1" /> 
      </ReportControl> 
      <ReportControl name="URCB02" rptID="PAC" datSet="PAC" > 
       <TrgOps dchg="true" qchg="true" period="true" /> 
       <OptFields configRef="true" /> 
      <RptEnabled max="1" /> 
      </ReportControl> 
      </LN0> 
     </LDevice> 
     </Server> 
    </AccessPoint> 
    </IED> 
</SCL> 

我需要一個轉換選擇所有ReportControl節點,其中@rptID="PAC"並插入一個孩子RptEnabled節點的節點,其屬性值取決於祖先節點的名稱屬性的值。

結果應該是這樣的:

<SCL> 
    <IED name="D60_220SW1"> 
    <AccessPoint name="S1"> 
     <Server> 
     <LDevice inst="Master"> 
      <LN0 lnClass="LLN0" inst="" lnType="LLN0_0"> 
      <ReportControl name="URCB01" rptID="XYZ" > 
       <TrgOps dchg="true" /> 
       <OptFields configRef="true" /> 
      <RptEnabled max="1" /> 
      </ReportControl> 
      <ReportControl name="URCB02" rptID="PAC" datSet="PAC" > 
       <TrgOps dchg="true" qchg="true" period="true" /> 
       <OptFields configRef="true" /> 
       <RptEnabled max="1" > 
       <ClientLN iedName="APACC_1" apRef="S2" ldInst="LD0" lnClass="ITCI" lnInst="1" /> 
       </RptEnabled> 
      </ReportControl> 
      </LN0> 
     </LDevice> 
     </Server> 
    </AccessPoint> 
    </IED> 
</SCL> 

插入ClientLN節點上的iedNameapRef屬性的值由IED祖先節點上的名稱屬性的值來確定。這樣的(我使用C#僞代碼來說明):

iedName="APACC_" + name.Contains("_220") ? "1": "2" 

我敢肯定,這是可行的,但我想不通怎麼了,我沒能找到一個適用的例子。

+0

什麼是「選擇所有ReportControl節點,其中@ rptID =‘PAC’」意味着什麼,你的例子只有與屬性的單個元素,你只是想改變任何這樣的元素所描述的還是你需要將所有這些元素組合在一起?對於「我無法找到適用的示例」,我確信任何轉換示例或任何使用標識轉換的XSLT教程以及匹配這些元素的模板都可以作爲一個起點,請嘗試一下。 –

回答

1

以下XSLT完成這項工作。但是因爲您沒有提供生成ClientLN節點的其他屬性的規則,所以我(迄今爲止)僅從您期望的輸出中複製了它們。您應該很容易地填寫所需的值。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" /> 

    <xsl:template match="node()|@*">      <!-- identity transform --> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ReportControl[@rptID = 'PAC']"> <!-- replace special nodes --> 
    <xsl:copy> 
     <xsl:apply-templates select="node()[not(self::RptEnabled)]|@*" /> 
     <RptEnabled> 
     <xsl:copy-of select="RptEnabled/@*" /> 
     <ClientLN apRef="S2" ldInst="LD0" lnClass="ITCI" lnInst="1"> 
      <xsl:attribute name="iedName"> 
      <xsl:choose> 
       <xsl:when test="contains(ancestor::IED/@name,'_220')">APACC_1</xsl:when> 
       <xsl:otherwise>APACC_2</xsl:otherwise> 
      </xsl:choose> 
      </xsl:attribute> 
     </ClientLN> 
     </RptEnabled> 
    </xsl:copy>  
    </xsl:template>  
</xsl:stylesheet> 
+1

您可以直接爲'match =「ReportControl [@rptID ='PAC']/RptEnabled」'編寫模板,不需要爲父元素編寫一個模板,因爲標識轉換需要處理該模板。 –

+0

完美。謝謝。 –