在其他结构中搜索具有相同名称的节点并替换其值之后,如何复制匹配节点的父节点?
我可以在模板中为每个孩子的父母设置密钥吗?
从此
<Message>
<XMLNSC>
<MaXML>
<Rule>
<A>RuleA</A>
<D>RuleD</D>
</Rule>
<Body>
<A>valA</A>
<B>valB</B>
<C>
<D>valD</D>
</C>
</Body>
</MaXML>
</XMLNSC>
为此,
<Message>
<XMLNSC>
<MaXML>
<Rule>
<A>RuleA</A>
<D>RuleD</D>
</Rule>
<Body>
<A>RuleA</A>
<A>RuleA</A>
<B>valB</B>
<C>
<D>RuleD</D>
<D>RuleD</D>
</C>
<C>
<D>RuleD</D>
<D>RuleD</D>
</C>
</Body>
<Body>
<A>RuleA</A>
<A>RuleA</A>
<B>valB</B>
<C>
<D>RuleD</D>
<D>RuleD</D>
</C>
<C>
<D>RuleD</D>
<D>RuleD</D>
</C>
</Body>
</MaXML>
</XMLNSC>
我的XSLT, https://xsltfiddle.liberty-development.net/pPqsHTK/5
答案 0 :(得分:1)
如果您为MaXML
的后代编写模板,这些子代具有一个键匹配的子元素,则只需在这些后代元素上使用两次身份模板,我就排除了Rule
元素然后明确地:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="ref" match="MaXML/Rule/*" use="concat(generate-id(ancestor::MaXML), '|', name())"/>
<xsl:template match="MaXML//*[not(self::Rule)][*[key('ref', concat(generate-id(ancestor::MaXML), '|', name()))]]">
<xsl:call-template name="identity"/>
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="Body//*[key('ref', concat(generate-id(ancestor::MaXML), '|', name()))]">
<xsl:copy>
<xsl:value-of select="key('ref', concat(generate-id(ancestor::MaXML), '|', name()))"/>
</xsl:copy>
<!-- duplicate matched node -->
<xsl:element name="{name()}">
<xsl:value-of select="key('ref', concat(generate-id(ancestor::MaXML), '|', name()))"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPqsHTK/6
使用XSLT 3,它会更容易一些:
<xsl:template match="MaXML//*[not(self::Rule)][*[key('ref', node-name(), ancestor::MaXML)]]">
<xsl:next-match/>
<xsl:next-match/>
</xsl:template>