Php 为什么<;面积>;元素导致XSLT删除元素内容和结束标记?

Php 为什么<;面积>;元素导致XSLT删除元素内容和结束标记?,php,xslt,Php,Xslt,在PHP5.2.11下运行XSLTprocessor时,我遇到了一个奇怪的错误,并且能够用复制它 这是流线型案例,它仍然会产生bug。 我的目标是采用层次结构的XML并“展平”它以创建行结构 输入: <?xml version="1.0"?> <profiles> <Subrecipient> <SubrecipientName>TESTING123</SubrecipientName> <Service>

在PHP5.2.11下运行XSLTprocessor时,我遇到了一个奇怪的错误,并且能够用复制它

这是流线型案例,它仍然会产生bug。 我的目标是采用层次结构的XML并“展平”它以创建行结构

输入:

<?xml version="1.0"?>
<profiles>
<Subrecipient>
    <SubrecipientName>TESTING123</SubrecipientName>
    <Service>
        <ServiceName>BEFORE</ServiceName>
        <area>BETWEEN</area>
        <TypeDesc>AFTER</TypeDesc>
    </Service>
</Subrecipient>
</profiles>

测试123
之前
之间
之后
样式表:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<!--generally, don't output nodes that have no children -->
<xsl:template match="//*[not(*)]" />
<!-- except in "dataout" mode, namely when we're matching at a low level -->
<xsl:template match="//*[not(*)]" mode="dataout" >
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="Service">
<row>
<!--next line selects all childless children of ancestors -->
<xsl:apply-templates select="ancestor::*/child::*[not(*)]" mode="dataout" />
<xsl:apply-templates  select="*[not(*)]" mode="dataout"  /> 
</row>
</xsl:template>
</xsl:stylesheet>

所需输出(为清晰起见,间距):

TESTING123
之前
之间
之后
实际输出(例如,来自上面链接的W3XSLT演示):

TESTING123
之前
之后
也就是说,XSLT过程生成错误的xml,省略了“area”元素的内容和结束标记。如果我将该元素重命名为“area_”,则一切正常

我不知道W3Schools使用的是什么XSLT处理器,所以可能这只是一个PHP XSLT处理器错误,或者XSLT和XPATH有一些深层次的(美妙的?)我不理解


我有一个解决办法,但我更愿意了解我在这里遇到了什么。谢谢你的帮助。

是的,这是正确的;造成这种情况的主要原因是,您正在将
xsl:output
与html方法一起使用。这样,处理器就可以输出格式不正确的文档。
area
标记是一个没有结束标记的HTML标记,其他许多标记如
br
等等。您可以通过将输出方法更改为XML来解决问题

<xsl:output method="xml"/>


您可能会在任何兼容XSLT 1.0的处理器(如Saxon 6.5)上体验到相同的行为。

这是我在W3S演示中得到的输出:

<row>
    <subrecipientname>TESTING123</subrecipientname>
    <servicename>BEFORE</servicename>
    <area>BETWEEN</area>
    <typedesc>AFTER</typedesc>
</row>

测试123
之前
之间
之后

需要注意的一点是,area是一个html元素,因此您可能会遇到问题。

W3Schools可能将XML
元素误认为是html的空
元素,并删除了内容。我尝试了其他一些空HTML元素,比如
,它们给出了相同的结果。很奇怪。再说一次,学校在很多事情上搞砸了,所以就这样。不过我不确定PHP的XSLT实现。@BoltClock-Bingo!(谢谢)我也在我的PHP代码中尝试了你的想法,我们可能已经发现了PHP XSLT实现的一个bug。当我将“area”元素重命名为“basefont”时,我会遇到完全相同的问题。古怪的遗憾的是,bugs.php.net现在已经关闭了。有趣的是,这只会影响某些HTML空元素。像
这样的其他人似乎做得很好。可能是因为
在RSS/RDF/Atom规范中是一个非空元素。
是您要求的,所以它被交付给了您。计算机只能由你指挥。谢谢,empo。这就解决了问题。我对XSLT的爱与恨加深了。不,不要责怪HTML,责怪你自己。如果你要求HTML输出格式,但想要XML,那只能怪你自己。W3C与W3C.LOL无关,这很有趣。我甚至都没意识到是我干的。
<xsl:output method="xml"/>
<row>
    <subrecipientname>TESTING123</subrecipientname>
    <servicename>BEFORE</servicename>
    <area>BETWEEN</area>
    <typedesc>AFTER</typedesc>
</row>