我有一个 xml 文档,如下所示:
<p>
<c1 />
<c2 />
</p>
Run Code Online (Sandbox Code Playgroud)
子元素 c1 和 c2 是可选的,但对于处理步骤,我需要它们存在。所以我试图创建一个 xslt 样式表来将它们添加为空元素(子元素的顺序无关紧要)。
这是我的样式表:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[not(c1)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<c1 />
</xsl:copy>
</xsl:template>
<xsl:template match="p[not(c2)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<c2 />
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
只要仅缺少一个子元素,这就可以正常工作。但如果两者都缺失,则只创建 c1。我如何防止并强制创建 c1 和 c2(实际上大约有 10 个孩子)?
谢谢。约斯特
我会这样做:
<xsl:template match="p">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:if test="not(c1)">
<c1 />
</xsl:if>
<xsl:if test="not(c2)">
<c2 />
</xsl:if>
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
如果您有更长的可能子节点列表,您可以将它们放入变量中并使用 afor-each而不是 individual if:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="childrenFragment">
<c1/>
<c2/>
</xsl:variable>
<xsl:template match="p">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:variable name="this" select="."/>
<xsl:for-each select="msxsl:node-set($childrenFragment)/*">
<xsl:variable name="localName" select="local-name()"/>
<xsl:if test="not($this/*[local-name()=$localName])">
<xsl:element name="{$localName}"/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
只需在变量中添加所需的所有元素即可childrenFragment。
(该msxsl:node-set内容是 Microsoft 特定的,如果您使用其他 XSLT 处理器,则需要稍微不同的内容)
| 归档时间: |
|
| 查看次数: |
4566 次 |
| 最近记录: |