假设我们在XML中有这样的嵌套列表:
<section name="SomeSection">
<!-- list property -->
<property length="2" name="ExternalList">
<!-- first element of external list -->
<listItem name="ExtElement1">
<property length="3" name="InternalList1">
<listItem name="SomeElement1" />
<listItem name="SomeElement2" />
<listItem name="SomeElement3" />
</property>
</listItem>
<!-- second element of external list -->
<listItem name="ExtElement2">
<property length="2" name="InternalList1">
<listItem name="SomeElement1" />
<listItem name="SomeElement2" />
</property>
</listItem>
</property>
</section>
我们有一些新项目,例如:
<listItem name="SomeElement3" />
什么转换在'ExtElement2'处向'InternalList1'添加'SomeElement3',以及 增加'InternalList1'的'length'属性?
感谢。
答案 0 :(得分:1)
这个简短的转换使用并覆盖了身份规则:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"property[@name='ExternalList']
/listItem[@name='ExtElement2']
/property[@name='InternalList1']
">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="length">
<xsl:value-of select="@length+1"/>
</xsl:attribute>
<xsl:apply-templates/>
<listItem name="SomeElement3" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<section name="SomeSection">
<!-- list property -->
<property length="2" name="ExternalList">
<!-- first element of external list -->
<listItem name="ExtElement1">
<property length="3" name="InternalList1">
<listItem name="SomeElement1" />
<listItem name="SomeElement2" />
<listItem name="SomeElement3" />
</property></listItem>
<!-- second element of external list -->
<listItem name="ExtElement2">
<property length="2" name="InternalList1">
<listItem name="SomeElement1" />
<listItem name="SomeElement2" />
</property></listItem>
</property>
</section>
产生了想要的正确结果:
<section name="SomeSection"><!-- list property -->
<property length="2" name="ExternalList"><!-- first element of external list -->
<listItem name="ExtElement1">
<property length="3" name="InternalList1">
<listItem name="SomeElement1"/>
<listItem name="SomeElement2"/>
<listItem name="SomeElement3"/>
</property>
</listItem><!-- second element of external list -->
<listItem name="ExtElement2">
<property length="3" name="InternalList1">
<listItem name="SomeElement1"/>
<listItem name="SomeElement2"/>
<listItem name="SomeElement3"/>
</property>
</listItem>
</property>
</section>
请注意:绝对不会在此解决方案的任何位置使用条件XSLT指令 - 它们根本不是必需的。
答案 1 :(得分:0)
这是一个简单的样式表,它将新元素的详细信息作为参数:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="extElement" select="'ExtElement2'" />
<xsl:param name="intElement" select="'SomeElement3'" />
<xsl:template match="property[@name='ExternalList']/listItem">
<xsl:choose>
<xsl:when test="@name = $extElement">
<listItem name="{$extElement}">
<property length="{property/@length+1}" name="{property/@name}">
<xsl:apply-templates select="property/listItem" />
<listItem name="{$intElement}" />
</property>
</listItem>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="identity" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
或者,如果您想将其硬编码到样式表中,您可以执行以下操作:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="listItem[@name='ExtElement2']/property">
<property length="{@length + 1}">
<xsl:apply-templates select="@*[name() != 'length'] | node()"/>
<listItem name="SomeElement3" />
</property>
</xsl:template>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是你需要在模板的match属性中指定你想要的位置。