gpt4 book ai didi

PHP XSLTProcessor transformToXml 返回 null

转载 作者:数据小太阳 更新时间:2023-10-29 02:29:24 29 4
gpt4 key购买 nike

我正在更新我的脚本以将我们的代码从 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 中工作,并且根据(我能找到的)关于所用类(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 的操作的正确结果。你为什么要问?这是您遇到的一系列问题:

  1. 您的 XML 文档中没有定义“vac”命名空间。您的 XML 显然无效。
  2. 在 xsl:stylesheet 中的 XSL 中没有定义“vac”命名空间。您的 XSL 根本不知道“vac” namespace 。因此,无论您做什么,vac: 元素都将保持不可见状态。
  3. 您的 XPath 语句引用没有限定命名空间的元素:将使用默认命名空间。但是您的 XML 中没有任何具有默认命名空间的元素。因此你得到 NULL - NOTHING TO PROCESS!

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>
  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;

关于PHP XSLTProcessor transformToXml 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32559892/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com