如何在 php 页面中显示 XML 外部实体?
How can I show XML external entities in a php page?
我目前正在做一个小图书馆项目,使用 XML 定义书籍,php 使用 title/author 进行搜索,然后在浏览器中显示该特定书籍。
所以我在 XML 文件中制作了一堆书,然后将这些文件作为外部实体链接到我的主 XML 文件中。我使用 DTD 定义实体,使用 XSD 文件为我的 xml 文件定义方案(我需要使用 XSD,但它不允许我定义实体,所以我也制作了一个 DTD)。所有文件都经过验证,当显示一本书时,或者如果我将所有书籍放在同一个 xml 文件中而不使用实体,它就可以正常工作。但是当我尝试使用仅包含实体的 xml 主文件时,它无法识别它们,并在没有显示任何内容的情况下向我发出以下警告:
Warning: simplexml_load_file(): test.xml:6: parser error : Entity 'book1' not defined in C:\xampp\htdocs\xml\test.php on line 14
Warning: simplexml_load_file(): &book1; in C:\xampp\htdocs\xml\test.php on line 14
我的 php 脚本如下:
<? $xml=simplexml_load_file("test.xml") or die("Error: Cannot create object");
foreach($xml->children() as $books) {?>
<b>Title:</b> <span id = "title"><? echo $books->title?></span><br>
<b>Authors:</b> <span id = "authors"><? echo $books->authors?></span><br>
<b>Publication date:</b> <span id = "pdate"><? echo $books->publication_date?></span><br>
<b>Publisher:</b> <span id = "publisher"><? echo $books->publisher?></span>
<?}?>
我的主要 XML 是这样的(我的每一本书都重复那本书):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="test.xsl "?>
<!DOCTYPE biblio SYSTEM "test.dtd">
<biblio xsi:noNamespaceSchemaLocation="test.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
&book1;
&book2;
&book3;
</biblio>
以下是 DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT biblio (livre+)>
<!ATTLIST biblio
xsi:noNamespaceSchemaLocation CDATA #IMPLIED
xmlns:xsi CDATA #IMPLIED>
<!ELEMENT livre (bookID,title,authors,publication_date?,publisher*)>
<!ELEMENT bookID (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT authors (#PCDATA)>
<!ELEMENT publication_date (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
<!ENTITY book1 SYSTEM "book1.xml">
<!ENTITY book2 SYSTEM "book2.xml">
<!ENTITY book3 SYSTEM "book3.xml">
和XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="biblio">
<xsd:complexType>
<xsd:sequence>
<xsd:element name= "livre" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bookID" type="xsd:integer"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="authors" type="xsd:string"/>
<xsd:element name="publication_date" type="xsd:date"/>
<xsd:element name="publisher" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
最后,这是我的示例 book.xml:
<?xml version="1.0" encoding="UTF-8"?>
<livre>
<bookID>1</bookID>
<title>Harry Potter and the Half-Blood Prince (Harry Potter #6)</title>
<authors>J.K. Rowling/Mary GrandPré</authors>
<publication_date>2006-09-16</publication_date>
<publisher>Scholastic Inc.</publisher>
</livre>
PS:我在浏览器上使用 xampp 到 运行 php。
编辑:经过一些测试,我开始明白我存储文件的方式,它只显示它包含的所有内容并且不像我那样读取它,我尝试了 运行ning php 在 cmd 提示符下,我可以看到它按原样打印 xml 文件,所以我想我应该找到一种方法来指定它应该如何解释 xml 文件内容。
编辑 2:我更改为简单XML,现在我可以根据需要显示书籍信息,但我不知道如何显示实体内容。
好吧,我找到了解决问题的方法,我不得不在 simplexml_load_file
函数中使用 SimpleXMLElement
属性和一些 libxml 选项,如下所示:
$xml=simplexml_load_file("test.xml",'SimpleXMLElement', LIBXML_DTDLOAD | LIBXML_NOENT) or die("Error: Cannot create object");
foreach($xml->children() as $books) {?>
<b>Title:</b> <span id = "title"><? echo $books->title?></span><br>
<b>Authors:</b> <span id = "authors"><? echo $books->authors?></span><br>
<b>Publication date:</b> <span id = "pdate"><? echo $books->publication_date?></span><br>
<b>Publisher:</b> <span id = "publisher"><? echo $books->publisher?></span>
<?}?>
第一个LIBXML_DTDLOAD
加载外部子集和第二个LIBXML_NOENT
替换实体官方文件:
https://www.php.net/manual/en/libxml.constants.php .
注意:要使用多个 LIBXML 常量,您应该用竖线将它们分开。
(感谢本文档中的第一条注释:
https://www.php.net/manual/en/function.simplexml-load-string.php#101594 )
我目前正在做一个小图书馆项目,使用 XML 定义书籍,php 使用 title/author 进行搜索,然后在浏览器中显示该特定书籍。 所以我在 XML 文件中制作了一堆书,然后将这些文件作为外部实体链接到我的主 XML 文件中。我使用 DTD 定义实体,使用 XSD 文件为我的 xml 文件定义方案(我需要使用 XSD,但它不允许我定义实体,所以我也制作了一个 DTD)。所有文件都经过验证,当显示一本书时,或者如果我将所有书籍放在同一个 xml 文件中而不使用实体,它就可以正常工作。但是当我尝试使用仅包含实体的 xml 主文件时,它无法识别它们,并在没有显示任何内容的情况下向我发出以下警告:
Warning: simplexml_load_file(): test.xml:6: parser error : Entity 'book1' not defined in C:\xampp\htdocs\xml\test.php on line 14
Warning: simplexml_load_file(): &book1; in C:\xampp\htdocs\xml\test.php on line 14
我的 php 脚本如下:
<? $xml=simplexml_load_file("test.xml") or die("Error: Cannot create object");
foreach($xml->children() as $books) {?>
<b>Title:</b> <span id = "title"><? echo $books->title?></span><br>
<b>Authors:</b> <span id = "authors"><? echo $books->authors?></span><br>
<b>Publication date:</b> <span id = "pdate"><? echo $books->publication_date?></span><br>
<b>Publisher:</b> <span id = "publisher"><? echo $books->publisher?></span>
<?}?>
我的主要 XML 是这样的(我的每一本书都重复那本书):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="test.xsl "?>
<!DOCTYPE biblio SYSTEM "test.dtd">
<biblio xsi:noNamespaceSchemaLocation="test.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
&book1;
&book2;
&book3;
</biblio>
以下是 DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT biblio (livre+)>
<!ATTLIST biblio
xsi:noNamespaceSchemaLocation CDATA #IMPLIED
xmlns:xsi CDATA #IMPLIED>
<!ELEMENT livre (bookID,title,authors,publication_date?,publisher*)>
<!ELEMENT bookID (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT authors (#PCDATA)>
<!ELEMENT publication_date (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
<!ENTITY book1 SYSTEM "book1.xml">
<!ENTITY book2 SYSTEM "book2.xml">
<!ENTITY book3 SYSTEM "book3.xml">
和XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="biblio">
<xsd:complexType>
<xsd:sequence>
<xsd:element name= "livre" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bookID" type="xsd:integer"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="authors" type="xsd:string"/>
<xsd:element name="publication_date" type="xsd:date"/>
<xsd:element name="publisher" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
最后,这是我的示例 book.xml:
<?xml version="1.0" encoding="UTF-8"?>
<livre>
<bookID>1</bookID>
<title>Harry Potter and the Half-Blood Prince (Harry Potter #6)</title>
<authors>J.K. Rowling/Mary GrandPré</authors>
<publication_date>2006-09-16</publication_date>
<publisher>Scholastic Inc.</publisher>
</livre>
PS:我在浏览器上使用 xampp 到 运行 php。
编辑:经过一些测试,我开始明白我存储文件的方式,它只显示它包含的所有内容并且不像我那样读取它,我尝试了 运行ning php 在 cmd 提示符下,我可以看到它按原样打印 xml 文件,所以我想我应该找到一种方法来指定它应该如何解释 xml 文件内容。
编辑 2:我更改为简单XML,现在我可以根据需要显示书籍信息,但我不知道如何显示实体内容。
好吧,我找到了解决问题的方法,我不得不在 simplexml_load_file
函数中使用 SimpleXMLElement
属性和一些 libxml 选项,如下所示:
$xml=simplexml_load_file("test.xml",'SimpleXMLElement', LIBXML_DTDLOAD | LIBXML_NOENT) or die("Error: Cannot create object");
foreach($xml->children() as $books) {?>
<b>Title:</b> <span id = "title"><? echo $books->title?></span><br>
<b>Authors:</b> <span id = "authors"><? echo $books->authors?></span><br>
<b>Publication date:</b> <span id = "pdate"><? echo $books->publication_date?></span><br>
<b>Publisher:</b> <span id = "publisher"><? echo $books->publisher?></span>
<?}?>
第一个LIBXML_DTDLOAD
加载外部子集和第二个LIBXML_NOENT
替换实体官方文件:
https://www.php.net/manual/en/libxml.constants.php .
注意:要使用多个 LIBXML 常量,您应该用竖线将它们分开。 (感谢本文档中的第一条注释: https://www.php.net/manual/en/function.simplexml-load-string.php#101594 )