我需要遍历XML树并确保某些元素附加了一个属性,如果缺少则添加它。需要这些属性的元素都具有公共元素名称前缀,并且具有此前缀的所有元素都需要属性。
这是一个人为的例子,因为我无法分享实际的XML:
<people>
<person>
<PRJ_NAME>Bob</PRJ_NAME>
<PRJ_AGE>22</PRJ_AGE>
<address>
<PRJ_FIRST_LINE>1 Test Street</PRJ_FIRST_LINE>
<PRJ_SECOND_LINE>London</PRJ_SECOND_LINE>
</address>
</person>
<person>
<PRJ_NAME>Tony</PRJ_NAME>
<PRJ_AGE>43</PRJ_AGE>
<address>
<PRJ_FIRST_LINE>23 Test Lane</PRJ_FIRST_LINE>
<PRJ_SECOND_LINE>Edinburgh</PRJ_SECOND_LINE>
</address>
</person>
</people>
所需的输出是将m
(已修改)属性添加到前缀为PRJ_
的所有元素。这些元素嵌套到不同的级别,并且树是非平凡的,所以我不能只对路径进行硬编码:
<people>
<person>
<PRJ_NAME m="2015-11-09">Bob</PRJ_NAME>
<PRJ_AGE m="2015-11-09">22</PRJ_AGE>
<address>
<PRJ_FIRST_LINE m="2015-11-09">1 Test Street</PRJ_FIRST_LINE>
<PRJ_SECOND_LINE m="2015-11-09">London</PRJ_SECOND_LINE>
</address>
</person>
<person>
<PRJ_NAME m="2015-11-09">Tony</PRJ_NAME>
<PRJ_AGE m="2015-11-09">43</PRJ_AGE>
<address>
<PRJ_FIRST_LINE m="2015-11-09">23 Test Lane</PRJ_FIRST_LINE>
<PRJ_SECOND_LINE m="2015-11-09">Edinburgh</PRJ_SECOND_LINE>
</address>
</person>
</people>
到目前为止,我一直在根据其他SO答案开展工作,例如adding attribute to the node,它适用于单个元素名称,但我很难将其应用于元素名称的模式:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:variable name="dateNow" select="format-date(current-date(), '[Y0001]-[M01]-[D01]')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PRJ_FIRST_NAME">
<PRJ_FIRST_NAME m="{$dateNow}">
<xsl:apply-templates select="@*|node()"/>
</PRJ_FIRST_NAME>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
将该模板更改为
<xsl:template match="*[starts-with(local-name(), 'PRJ_') and not(@m)]">
<xsl:element name="{name()}">
<xsl:attribute name="m" select="$dateNow"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
并且您的方法很好,但我想要获得您在结果示例中显示的格式,您需要使用<xsl:variable name="dateNow" select="format-date(current-date(), '[Y0001]-[M01]-[D01]')"/>
。