我现在可以看到,我对XSL很陌生。
假设我输入了
<?xml version="1.0" encoding="UTF-8"?>
<Doc>
<A>A</A>
<B>B</B>
<C>C</C>
</Doc>
并将其传递给XSLT,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="A">
<xsl:element name="Info">This is an <xsl:value-of select="."/></xsl:element>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
我会得到
<?xml version="1.0" encoding="UTF-8"?>
<Info>This is an A</Info>A
B
C
我怎样才能摆脱这些额外的A和其他B&C假设有一些复杂的树,我怎么能说只转换我模板中匹配的元素,省略其他所有?
最诚挚的问候和提前谢谢
答案 0 :(得分:1)
这是因为XSLT的built-in template rules。
有多种方法可以覆盖内置规则,例如添加与text()
匹配的空xsl:模板。
在您的特定情况下,我可能会在模板中添加一个选择xsl:apply-templates以匹配根元素(/*
)并从匹配的模板中删除xsl:apply-templates A
...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/*">
<xsl:apply-templates select="A"/>
</xsl:template>
<xsl:template match="A">
<xsl:element name="Info">This is an <xsl:value-of select="."/></xsl:element>
</xsl:template>
</xsl:stylesheet>
另请注意,如果您要创建新元素,则除非您动态创建名称,否则 不能使用xsl:element。只是输出它......
<Info>This is an <xsl:value-of select="."/></Info>
答案 1 :(得分:0)
您看到的附加输出是XSLT内置标准规则的效果。
这些说:“通过输入树递归并处理每个节点。对于元素节点,处理它们的子节点,对于文本节点,将它们的内容复制到输出。”
另请参阅more in-depth explanation #1和more in-depth explanation #2,当然还有the spec。
每当没有处理特定节点的规则(即模板)时,这些标准规则就会生效。
这就是这里发生的事情:
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
它读取:“匹配根节点和进程(即应用模板)任何子元素。”
这将处理根节点,并继续处理根节点的唯一子节点 - 文档元素<Doc>
。之后,处理器继续处理其子项。 <A>
有一个自定义模板,<B>
和<C>
没有自定义模板,这意味着将使用默认规则,其文本内容将以输出结束。
请注意,这也意味着上述模板是一个可以安全地完全丢弃的无操作模式,而不会对结果进行任何更改。它只是重新迭代默认规则会做什么。
出路:
制作一个与<B>
和<C>
匹配的自定义模板,不会产生任何输出:
<xsl:template match="B | C" />
创建一个与任何元素节点匹配的自定义模板,并且不生成任何输出:
<xsl:template match="*" />
这是因为匹配表达特异性。更具体的匹配表达式将优先于不太具体的匹配表达式,因此即使match="*"
也匹配<A>
,也会优先使用match="A"
的模板。
首先不要在已处理的节点中包含<B>
和<C>
:
<xsl:template match="/*">
<xsl:apply-templates select="A" />
</xsl:template>
请注意,match="/"
与根节点匹配,而match="/*"
与文档元素匹配(如上所述,存在差异)。您可以使用match="/Doc"
,这比/*
更具体。但是,/*
是表达“文档元素,无论它可能被称为”的常见约定。
这三种策略都是有效的,这取决于您想要使用的情况和您的偏好。