我的XML看起来像这样:
<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
节点的子节点,其属性值取决于{{name属性的值1}}祖先节点。
结果应如下所示:
IED
插入的<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>
节点上的iedName
和apRef
属性的值由ClientLN
祖先节点上的name属性的值确定。像这样(我用C#伪代码来说明):
IED
我确信这是可行的,但我无法弄清楚如何,而且我无法找到适用的例子。
答案 0 :(得分: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>