【发布时间】:2014-02-24 18:32:18
【问题描述】:
我正在使用仅支持 xsl 1.0 的 xmlstarlet 将一个 xml 转换为另一个。
我正在尝试查找属性“atr1”的值并在同一节点中插入另一个属性“atr2”。
当使用下面的 sample.xml 时
<a>
<b></b>
<c>
<d atr1="#{not MGR_1}" atr2="#{condition1}"></d>
<d atr1="#{ MGR_2}" ></d>
<d atr1="2"></d>
</c>
</a>
用下面的transform.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="d[contains(@atr1, 'MGR_')]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:attribute name="atr2">
<xsl:choose>
<xsl:when test="@atr2">
<xsl:value-of select="concat('#{', substring(@atr2,3,string-length(@atr2)-3), ' and not ', substring(@atr1,3))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('#{not ', substring(@atr1,3))" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我得到预期的 o/p 如下。
<a>
<b/>
<c>
<d atr1="#{not MGR_1}" atr2="#{condition1 and not not MGR_1}"/>
<d atr1="#{ MGR_2}" atr2="#{not MGR_2}"/>
<d atr1="2"/>
</c>
</a>
但是当我尝试使用下面的 xml 时。其中有另一个内部元素x,那么问题就来了。
<a>
<b></b>
<c>
<d atr1="#{not MGR_1}" atr2="#{condition1}"></d>
<d atr1="#{ MGR_2}" ></d>
<d atr1="2"></d>
<d atr1="#{ MGR_3}" >
<x>blah blah blah</x>
</d>
</c>
</a>
关于尝试转换上述 XML。我收到一条错误消息
$ xml tr transform.xsl sample.xml
runtime error: file transform.xsl line 14 element attribute
xsl:attribute: Cannot add attributes to an element if children have been already added to the element.
我哪里弄错了。在修改后的 XML 上获得所需 o/p 的正确 XSL 可能是什么。
【问题讨论】:
标签: xml xslt xmlstarlet