PHP XSLTProcessor transformToXml返回null

时间:2015-09-14 08:02:10

标签: php xml xslt

我正在更新我的脚本以将代码从Ubuntu 12.04(PHP 5.3.10)移动到Ubuntu 14.04(PHP 5.5.9),但是using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Diagnostics; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using EmoTEDTherapeute; namespace ControlSceneImage { public class SceneImage : PictureBox { public static readonly int defaultWidth = 100; public static readonly int defaultHeight = 100; static readonly int activePbPosY; // Position en Y des scènes actives static readonly Dictionary<string, Point> scenesPos = null; // Invariant, stocke la position initiale des PictureBox static readonly List<Point>[] activeScenesPos = null; // Invariant, stocke les positions des PictureBox en fonction du nombre de scènes actives static List<SceneImage> activeScenes = null; const int maxActiveScenes = 5; const int ecart = 80; const int decalage = 15; const int panelScenesWidth = 909; const int panelScenesHeight = 154; const int panelScenesLocationX = 35; const int panelScenesLocationY = 36; bool isActive; static SceneImage() { // Constructeur initialisant tous les membres statiques, n'est appelé qu'une seule fois, avant tout le reste activePbPosY = (panelScenesLocationY + panelScenesHeight - (int)(0.6 * defaultHeight)) / 2; scenesPos = new Dictionary<string, Point>(); activeScenesPos = new List<Point>[maxActiveScenes]; for (int i = 0; i < maxActiveScenes; i++) { activeScenesPos[i] = CalcActiveScenesPos(i+1); } activeScenes = new List<SceneImage>(); } public SceneImage() { MouseEnter += new EventHandler(OnMouseEnter); MouseDown += new MouseEventHandler(OnMouseDown); MouseUp += new MouseEventHandler(OnMouseUp); MouseLeave += new EventHandler(OnMouseLeave); BorderStyle = BorderStyle.FixedSingle; Size = new Size(defaultWidth, defaultHeight); SizeMode = PictureBoxSizeMode.Zoom; isActive = false; } private static List<Point> CalcActiveScenesPos(int nbActiveScenes) { List<Point> ret = new List<Point>(); for (int i = 0; i < nbActiveScenes; i++) { ret.Add(new Point((panelScenesLocationX + panelScenesWidth + ecart) / 2 + (int)((ecart + defaultWidth) * (i - nbActiveScenes / 2.0)) + decalage, activePbPosY)); } return ret; } private void UpdateScenesPos() { for(int i = 0; i < activeScenes.Count; i++) { activeScenes[i].Location = activeScenesPos[activeScenes.Count - 1][i]; } } private void OnMouseEnter(object sender, EventArgs e) { BackColor = Color.LightYellow; Cursor = Cursors.Hand; } private void OnMouseDown(object sender, MouseEventArgs e) { BorderStyle = BorderStyle.Fixed3D; } private void OnMouseUp(object sender, MouseEventArgs e) { if (!scenesPos.ContainsKey(Name)) { // Si ce n'est pas déjà fait, on stocke la position initiale de notre PictureBox scenesPos.Add(Name, Location); // Et on crée un Panel vide sous elle Panel panel = new Panel(); panel.Location = Location; panel.Size = Size; panel.BorderStyle = BorderStyle.Fixed3D; // On ajoute notre panel à notre form Form1.AddInSeance(panel); } if (!isActive) { activeScenes.Add(this); } else { Location = scenesPos[Name]; activeScenes.Remove(this); } isActive = !isActive; UpdateScenesPos(); } private void OnMouseLeave(object sender, EventArgs e) { BorderStyle = BorderStyle.FixedSingle; BackColor = Color.Transparent; } } } 一直返回NULL并且我不知道为什么。

  • 我有var_dump() - 几乎每个变量/对象并检查它的内容
  • 搜索许多不同的搜索字词

如前所述,这曾经在Ubuntu 12.04中工作,根据(我能找到),不同的PHP版本之间没有关于使用的类(DomDocument,XSLTProcessor)的更改。

如何让$result = $proc->transformToXml($xml);包含正确解析的XML输出?

这是我的PHP代码:

$result

XML:

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

和XSL:

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

2 个答案:

答案 0 :(得分:3)

你在错误的地方寻找问题。它与PHP无关。 PHP只使用libxml2,你最好诉诸xsltproc来检查是什么问题。运行:

xsltproc test.xsl test.xml

基本上它是SISO的经典案例。 XSLT刚刚返回正确的操作结果,恰好是NULL。你为什么要问?在这里你遇到的一系列问题:

  1. 没有定义&#39; vac&#39; XML文档中的命名空间。您的XML无效。
  2. 没有定义&#39; vac&#39; xsl:stylesheet中的XSL中的命名空间。您的XSL不知道&#39; vac&#39;命名空间。所以无论你做什么都是vac:元素将保持不可见。
  3. 您的XPath语句引用没有限定名称空间的元素:将使用默认名称空间。但是,您的XML中没有任何带有默认命名空间的元素。因此你得到NULL - 没有处理!
  4. PS:请帮自己一个忙,并在XML中使用<?xml version="1.0" encoding="utf-8"?>。否则你最终会遇到编码问题。

    PPS:关于你的评论,根据&#34; PHPDoc意味着它成功加载了XML&#34;。成功加载并不意味着您的XML是正确的。你得到了<nodename>上的名称空间前缀vac未在实体中定义&#34;有充分的理由。

    这里是正确的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. &#39;真空&#39;必须将名称空间添加到XML和XSL
    2. 然后XPath语句可以使用它
    3. 我添加了<vac:antwoordTekst>show me!</vac:antwoordTekst>,因为空元素的样式返回NULL。只是为了展示一些东西。
    4. 这些文件的结果是:

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

答案 1 :(得分:0)

如果有其他人遇到此问题,我必须utf_encode()我的$xml_file_contents才能使用,因为XML文档中有特殊字符。将<?xml version="1.0" encoding="UTF-8"?>声明添加到XML文档的顶部似乎无助于解析器处理utf-8特殊字符。