编程语言
首页 > 编程语言> > PHP XSLTProcessor transformToXml返回null

PHP XSLTProcessor transformToXml返回null

作者:互联网

我正在更新脚本,以将代码从Ubuntu 12.04(PHP 5.3.10)移至Ubuntu 14.04(PHP 5.5.9),但是$result = $proc-> transformToXml($xml);一直返回NULL,我不知道为什么.

>我已经对每个变量/对象几乎进行了var_dump()编辑,并检查了其内容
>搜索许多不同的搜索词

如前所述,它曾经在Ubuntu 12.04中工作,并且根据(我能找到的),关于所使用的类(DomDocument,XSLTProcessor),不同的PHP版本之间没有任何变化.

如何获得$result以包含正确解析的XML输出?

这是我的PHP代码:

$xml = new DomDocument();
$xml->loadXML($xml_file_contents, LIBXML_NOERROR);
$xml->normalizeDocument(); //Whether included or left out doesn't seem to make a difference

$xsl = new DomDocument();
$xsl->loadXML($xsl_file_contents);

$proc = new XSLTProcessor();
$proc->importStylesheet($xsl);

$result = $proc->transformToXml($xml);

XML:

<vac:body>
    <vac:kanaal type="generiek">
        <vac:vraag>Lorem Ipsum dolar sit amet</vac:vraag>
        <vac:antwoord
            xmlns="http://www.w3.org/1999/xhtml">
            <vac:antwoordTekst/>
            <vac:antwoordTekstErvoor/>
            <vac:antwoordTekstOrigineel/>
            <vac:antwoordTekstErna/>
            <vac:antwoordProductVeld>
                <![CDATA[<p>Lorem Ipsum dolar sit amet</p>]]>
            </vac:antwoordProductVeld>
            <vac:antwoordAdres/>
        </vac:antwoord>
        <vac:toelichting
            xmlns="http://www.w3.org/1999/xhtml">
            <![CDATA[]]>
        </vac:toelichting>
        <vac:onderwaterantwoord>
            <vac:onderwaterantwoordTekst/>
            <vac:onderwaterantwoordProductVeld/>
        </vac:onderwaterantwoord>
        <vac:formulieren/>
        <vac:contactinfo/>
    </vac:kanaal>
    <vac:verwijzingProduct resourceIdentifier="1337">Lorem ipsum</vac:verwijzingProduct>
    <vac:verwijzingVac resourceIdentifier="1337-01">Lorem Ipsum dolar sit amet</vac:verwijzingVac>
    <vac:verwijzingVac resourceIdentifier="1337-02">Lorem ipsum dolar sit amet</vac:verwijzingVac>
</vac:body>

和XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" />

    <xsl:template match="/">

        <xsl:call-template name="text">
            <xsl:with-param name="node" select="/body/kanaal/antwoord/antwoordTekst" />
        </xsl:call-template>

        <xsl:call-template name="text">
            <xsl:with-param name="node" select="/body/kanaal/antwoord/antwoordProductVeld" />
        </xsl:call-template>

        <xsl:call-template name="address">
            <xsl:with-param name="node" select="/body/kanaal/antwoord/antwoordAdres" />
        </xsl:call-template>

        <xsl:if test="/body/kanaal/verwijzingOverigeInfo" >
            <ul>
                <xsl:for-each select="/body/kanaal/verwijzingOverigeInfo" >
                    <xsl:call-template name="moreinfo">
                        <xsl:with-param name="node" select="self::node()" />
                    </xsl:call-template>
                </xsl:for-each>
            </ul>
        </xsl:if>

    </xsl:template>

    <xsl:template name="text">
        <xsl:param name="node" />
        <xsl:if test="normalize-space($node/text())">
            <xsl:value-of select="$node"/>
        </xsl:if>
    </xsl:template>

    <xsl:template name="address">
        <xsl:param name="node" />

        <xsl:for-each select="$node/instantie">
            <p class="vac_address">
                <xsl:for-each select="*">
                    <xsl:call-template name="address_element"/>
                </xsl:for-each>
            </p>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="address_element">
        <xsl:if test=". != ''">
            <xsl:element name="span">
                <xsl:attribute name="class">
                    <xsl:value-of select ="name(.)"/>
                </xsl:attribute>
                <xsl:value-of select="." disable-output-escaping="yes"/>
            </xsl:element>
        </xsl:if>
    </xsl:template>

    <xsl:template name="moreinfo">
        <xsl:param name="node" />

            <li>
                <xsl:element name="a">
                    <xsl:attribute name="href">
                        <xsl:value-of select="$node/@resourceIdentifier" />
                    </xsl:attribute>
                    <xsl:value-of select="$node" />
                </xsl:element>
            </li>
    </xsl:template>

</xsl:stylesheet>

解决方法:

您在错误的位置寻找问题.它与PHP无关. PHP仅使用libxml2,您最好使用xsltproc来检查错误.跑:

xsltproc test.xsl test.xml

基本上,这是SISO的经典案例. XSLT刚刚返回了恰好为NULL的正确操作结果.你为什么要问?以下是您遇到的所有问题:

> XML文档中没有’vac’名称空间的定义.您的XML完全无效.
> XSL:stylesheet中的XSL中没有’vac’名称空间的定义.您的XSL根本不知道’vac’命名空间.因此,无论您做什么vac:元素将保持不可见.
>您的XPath语句引用了没有限定名称空间的元素:将使用默认名称空间.但是您的XML中没有任何具有默认命名空间的元素.因此,您将得到NULL-无需处理!

PS:请帮个忙,并使用<?xml version =“ 1.0” encoding =“ utf-8”?>在您的XML中.否则,您最终会遇到编码问题.

PPS:关于您的评论,即“ PHPDoc表示它已成功加载XML”.成功加载并不意味着您的XML是正确的.您有充分的理由得到“实体中未定义< nodename>上的命名空间前缀vac”.

这里是正确的XML:

<?xml version="1.0" encoding="utf-8"?>
<vac:body xmlns:vac="http://standaarden.overheid.nl/vac">
    <vac:kanaal type="generiek">
        <vac:vraag>Lorem Ipsum dolar sit amet</vac:vraag>
        <vac:antwoord
            xmlns="http://www.w3.org/1999/xhtml">
            <vac:antwoordTekst>show me!</vac:antwoordTekst>
            <vac:antwoordTekstErvoor/>
            <vac:antwoordTekstOrigineel/>
            <vac:antwoordTekstErna/>
            <vac:antwoordProductVeld>
                <![CDATA[<p>Lorem Ipsum dolar sit amet</p>]]>
            </vac:antwoordProductVeld>
            <vac:antwoordAdres/>
        </vac:antwoord>
        <vac:toelichting
            xmlns="http://www.w3.org/1999/xhtml">
            <![CDATA[]]>
        </vac:toelichting>
        <vac:onderwaterantwoord>
            <vac:onderwaterantwoordTekst/>
            <vac:onderwaterantwoordProductVeld/>
        </vac:onderwaterantwoord>
        <vac:formulieren/>
        <vac:contactinfo/>
    </vac:kanaal>
    <vac:verwijzingProduct resourceIdentifier="1337">Lorem ipsum</vac:verwijzingProduct>
    <vac:verwijzingVac resourceIdentifier="1337-01">Lorem Ipsum dolar sit amet</vac:verwijzingVac>
    <vac:verwijzingVac resourceIdentifier="1337-02">Lorem ipsum dolar sit amet</vac:verwijzingVac>
</vac:body>

并更正XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vac="http://standaarden.overheid.nl/vac">
    <xsl:output method="xml" omit-xml-declaration="yes" />

    <xsl:template match="/">

        <xsl:call-template name="text">
            <xsl:with-param name="node" select="/vac:body/vac:kanaal/vac:antwoord/vac:antwoordTekst" />
        </xsl:call-template>

        <xsl:call-template name="text">
            <xsl:with-param name="node" select="/vac:body/vac:kanaal/vac:antwoord/vac:antwoordProductVeld" />
        </xsl:call-template>

        <xsl:call-template name="address">
            <xsl:with-param name="node" select="/vac:body/vac:kanaal/vac:antwoord/vac:antwoordAdres" />
        </xsl:call-template>

        <xsl:if test="/vac:body/vac:kanaal/vac:verwijzingOverigeInfo" >
            <ul>
                <xsl:for-each select="/vac:body/vac:kanaal/vac:verwijzingOverigeInfo" >
                    <xsl:call-template name="moreinfo">
                        <xsl:with-param name="node" select="self::node()" />
                    </xsl:call-template>
                </xsl:for-each>
            </ul>
        </xsl:if>

    </xsl:template>

    <xsl:template name="text">
        <xsl:param name="node" />
        <xsl:if test="normalize-space($node/text())">
            <xsl:value-of select="$node/text()"/>
        </xsl:if>
    </xsl:template>

    <xsl:template name="address">
        <xsl:param name="node" />

        <xsl:for-each select="$node/vac:instantie">
            <p class="vac_address">
                <xsl:for-each select="*">
                    <xsl:call-template name="address_element"/>
                </xsl:for-each>
            </p>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="address_element">
        <xsl:if test=". != ''">
            <xsl:element name="span">
                <xsl:attribute name="class">
                    <xsl:value-of select ="name(.)"/>
                </xsl:attribute>
                <xsl:value-of select="." disable-output-escaping="yes"/>
            </xsl:element>
        </xsl:if>
    </xsl:template>

    <xsl:template name="moreinfo">
        <xsl:param name="node" />

            <li>
                <xsl:element name="a">
                    <xsl:attribute name="href">
                        <xsl:value-of select="$node/@resourceIdentifier" />
                    </xsl:attribute>
                    <xsl:value-of select="$node" />
                </xsl:element>
            </li>
    </xsl:template>

</xsl:stylesheet>

>’vac’名称空间必须同时添加到XML和XSL中
> XPath语句然后可以使用它
>我添加了< vac:antwoordTekst>给我看!< / vac:antwoordTekst>因为空元素的样式返回NULL.只是为了展示一些东西.

这些文件的结果是:

show me!
                &lt;p&gt;Lorem Ipsum dolar sit amet&lt;/p&gt;

标签:xml,xslt,php
来源: https://codeday.me/bug/20191119/2038432.html