我有以下XML
<?xml version="1.0"?>
<people><human><sex>male</sex><naxme>Juanito</naxme>
</human>
<human><sex>female</sex><naxme>Petra</naxme></human>
<human><sex>male</sex><naxme>Anaximandro</naxme></human>
</people>
和这个XSL
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" indent="no"/>
<xsl:template match="/people/human[sex='male']">
<xsl:value-of select="naxme"/>
</xsl:template>
</xsl:stylesheet>
我希望它能过滤掉女性,它有点工作,但我得到了非匹配节点的奇数值:
Juanito
femalePetra
Anaximandro
我期待与
相同的输出<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" indent="no"/>
<xsl:template match="/people/human">
<xsl:if test = "sex='male'">
<xsl:value-of select="naxme"/>
</xsl:if> </xsl:template>
</xsl:stylesheet>
谢谢!
答案 0 :(得分:3)
这可能是因为XSLT的built-in template rules。尝试添加此模板:
<xsl:template match="text()"/>
答案 1 :(得分:3)
我将扩展Daniels的答案,其中包含了一些原因。
您获得两个不同输出的原因归结为built-in template rules,以及默认情况下如何处理节点和文本。
总结该链接,如果不存在其他模板,则会有默认模板确保每个节点 - 无论是元素,文本,属性,注释 - 都会受到欢迎,只是为了确保可以正确处理其他具有规则的节点
使用这个XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/people/human[sex='male']">
<xsl:value-of select="naxme"/>
</xsl:template>
</xsl:stylesheet>
你有一个明确的规则:
如果找到与XPath
/people/human[sex='male]
匹配的节点,请执行此模板。
与默认规则一起:
查找所有节点,然后处理所有子节点。如果是文本,只输出文本。
此默认规则是您的模板正在处理的原因,因为您没有明确的根节点规则 - /
- 除非另一个存在,否则使用默认规则处理任何子节点和孙节点。因此,除了匹配/people/human[sex='male]
的节点之外,使用默认值遍历每个节点。结果是当你有一个“女性”的节点时,文本正在吐出而不是被忽略。
然而,与此形成鲜明对比:
<xsl:template match="/people/human">
<xsl:if test = "sex='male'">
<xsl:value-of select="naxme"/>
</xsl:if>
</xsl:template>
规则变为:
如果找到与XPath
/people/human
匹配的节点,请执行此模板。
恰好在该模板中,你有一个额外的条件,如果它是男性,则以某种方式处理它,没有其他条件,所以如果遇到“女性”节点,它现在是空白的在输出中。
最后, Daniels回答原因但很容易破解的原因是,它改变了处理文本的规则。现在不是像默认规则一样复制所有文本,而是输出任何内容(根据空模板。但是,如果您有任何其他模板使用xsl:apply-templates
来处理文本并期待文本, >他们现在也不输出任何内容。