2016-12-30 57 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

完美。谢谢。 –