簡體   English   中英

PHP XSLTProcessor transformToXml返回null

[英]PHP XSLTProcessor transformToXml returns null

我正在更新我的腳本以將代碼從Ubuntu 12.04(PHP 5.3.10)移動到Ubuntu 14.04(PHP 5.5.9),但是$result = $proc->transformToXml($xml); 保持返回NULL,我不知道為什么。

  • 我有var_dump() - 幾乎每個變量/對象並檢查它的內容
  • 用Google搜索許多不同的搜索字詞

如上所述,這曾經在Ubuntu 12.04中工作,根據(我能找到的),不同的PHP版本之間沒有關於使用的類(DomDocument,XSLTProcessor)的變化。

如何獲得$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。 你為什么要問? 這里有你所遇到的一系列問題:

  1. XML文檔中沒有'vac'命名空間的定義。 您的XML無效。
  2. xsl:stylesheet中的XSL中沒有'vac'命名空間的定義。 您的XSL根本不知道'vac'命名空間。 所以無論你做什么,都會:元素仍然是隱形的。
  3. 您的XPath語句引用沒有限定名稱空間的元素:將使用默認名稱空間。 但是,XML中沒有任何帶有默認命名空間的元素。 因此你得到NULL - 沒有處理!

PS:請幫個忙,在你的<?xml version="1.0" encoding="utf-8"?>使用<?xml version="1.0" encoding="utf-8"?> 否則你最終會遇到編碼問題。

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>
  1. 必須將'vac'命名空間添加到XML和XSL中
  2. 然后XPath語句可以使用它
  3. 我添加了<vac:antwoordTekst>show me!</vac:antwoordTekst>因為空元素的樣式返回NULL。 只是為了展示一些東西。

這些文件的結果是:

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

如果其他人遇到這個問題,我必須utf_encode()我的$xml_file_contents才能工作,因為XML文檔中有特殊字符。 <?xml version="1.0" encoding="UTF-8"?>聲明添加到XML文檔的頂部似乎沒有幫助解析器處理utf-8特殊字符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM