我正在尝试根据节点(D)的值与“规则/项目”中的值的匹配来替换名称相同但结构不同的节点(D)。也许像每个人一样。
我正在使用两个键,一个具有新值,另一个具有旧值(可能没用),然后我逐个进行输入,但是具有新值的键没有给我任何东西。不应该工作吗?
另一个问题,我想复制匹配节点的父节点,而我的XSLT也将“项目”加倍。
输入
<Message>
<XMLNSC>
<Translator>
<Rule>
<Item>
<D>RuleD1</D>
<New>RuleD1</New> <!-- I guess I don't need an element for this -->
<Original>valD1</Original>
</Item>
<Item>
<D>RuleD2</D>
<New>RuleD2</New> <!-- I guess I don't need an element for this -->
<Original>valD2</Original>
</Item>
</Rule>
<Body>
<A>valA</A>
<B>valB</B>
<C>
<D>valD1</D>
</C>
<E>
<D>valD2</D>
</E>
</Body>
</Translator>
</XMLNSC>
期望
<Message>
<XMLNSC>
<Translator>
<Rule>
<Item>
<D>RuleD1</D>
<New>RuleD1</New> <!-- I guess I don't need an element for this -->
<Original>valD1</Original>
</Item>
<Item>
<D>RuleD2</D>
<New>RuleD2</New> <!-- I guess I don't need an element for this -->
<Original>valD2</Original>
</Item>
</Rule>
<Body>
<A>valA</A>
<B>valB</B>
<C>
<D>RuleD1</D>
<D_Agg>val1</D_Agg>
</C>
<C>
<D>RuleD1</D>
<D_Agg>val1</D_Agg>
</C>
<E>
<D>RuleD2</D>
<D_Agg>val2</D_Agg>
</E>
<E>
<D>RuleD2</D>
<D_Agg>val2</D_Agg>
</E>
</Body>
</Translator>
</XMLNSC>
这是我的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<!-- copy nodes -->
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="ref" match="Translator/Rule//*" use="concat(generate-id(ancestor::Translator), '|', name())"/>
<xsl:key name="ref_new" match="New" use="text()"/>
<xsl:key name="ref_origin" match="Original" use="text()"/>
<!-- duplicate matched node's parent -->
<xsl:template match="Translator//*[not(self::Rule)][*[key('ref', concat(generate-id(ancestor::Translator), '|', name()))]]">
<xsl:call-template name="identity"/>
<xsl:call-template name="identity"/>
</xsl:template>
<!-- replace matched node's value -->
<xsl:template match="Body//*[key('ref', concat(generate-id(ancestor::Translator), '|', name()))]">
<xsl:variable name="fieldName" select="name()"/>
<xsl:variable name="fieldValue" select="."/>
<!-- <xsl:copy> -->
<!-- <xsl:value-of select="key('ref', concat(generate-id(ancestor::Translator), '|', name()))"/> -->
<!-- </xsl:copy> -->
<xsl:for-each select="key('ref_new', text())">
<xsl:element name="{$fieldName}">
<xsl:value-of select="$fieldValue"/>
</xsl:element>
</xsl:for-each>
<xsl:for-each select="key('ref_origin', text())">
<xsl:element name="{$fieldName}_Agg">
<xsl:value-of select="$fieldValue"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
由于您的XSLT样式表很复杂,并且我不知道什么很重要,因此我尝试尽可能少地更改以实现所需的结果。
我将您的第二个xsl:key
更改为
<xsl:key name="ref_origin" match="Item" use="Original"/>
这使得D
子级可以访问,该子级在最后一个xsl:for-each
中使用,但是保留了密钥的值。
我更改了您的 identity 调用方模板,以避免通过在第二个调用周围添加Item
来使xsl:if
元素加倍
<!-- duplicate matched node's parent -->
<xsl:template match="Translator//*[not(self::Rule)][*[key('ref', concat(generate-id(ancestor::Translator), '|', name()))]]">
<xsl:call-template name="identity" />
<xsl:if test="not(self::Item)">
<xsl:call-template name="identity" />
</xsl:if>
</xsl:template>
我在最后一个xsl:for-each
上添加了另一个元素,以添加D
元素,该元素可从上述xsl:key
访问
<xsl:for-each select="key('ref_origin', text())">
<xsl:element name="{$fieldName}">
<xsl:value-of select="D"/> <!-- Using the D child of the Item from the key -->
</xsl:element>
<xsl:element name="{$fieldName}_Agg">
<xsl:value-of select="$fieldValue"/>
</xsl:element>
</xsl:for-each>
现在输出应该如预期的那样。