我只是停留在一个我认为没有那么难解决的问题上。
我正在开发一个可以上传和下载xml文件的网站。 xml文件必须完全读取,我想将信息写入数据库。
可能的结构数量有限,但未定义上载文档中存在的结构。这必须由系统本身来识别。理想情况下,应该可以从数据库中的条目重新创建上载的文档。
应阅读文档的所有元素。特别重要:
我附上了两个样本文件。这些文件实际上更加广泛。我只是想尽可能简单地提出问题。
关于PHP类/库/函数可以满足我的要求的提示,我将非常感激。我一直在看整个星期天,但我只在圈子里移动...
我不是专业的PHP开发人员,这只是一个休闲项目。如果这个问题容易回答,请亲切。
inhabitants.xml:
<?xml version="1.0"?>
<!DOCTYPE inhabitants [
<!ENTITY cName "Ultra Long Surname">
]>
<inhabitants>
<inhabitant alias="bob">Bob &cName;</inhabitant>
<inhabitant alias="tom">Tom &cName;</inhabitant>
<inhabitant alias="tim">Tim Short</inhabitant>
<inhabitant alias="leo">Leo Short</inhabitant>
</inhabitants>
streets.xml:
<?xml version="1.0"?>
<districts>
<district name="d1">
<street size="small">Nameless street</street>
<street size="long">Sutton Lane</street>
</district>
<district name="d2">
<!-- Not explored -->
<street size="unknown">Street of Death</street>
</district>
</districts>
我最后一次尝试或已经发现的结果:
<?php
$dom = new DOMDocument();
$dom->load('files/inhabitants.xml');
// How to get "Ultra Long Surname" ?
echo 'Value of "cName": '.$dom->doctype->entities->item(0)->nodeValue;
// Output: "Value of "cName": "
// How do I get a list of all tags?
foreach ($dom->getElementsByTagName('inhabitant') as $inhabitant){
if ($inhabitant instanceof DOMElement){
echo $inhabitant->getAttribute('alias');
echo ' - ';
echo $inhabitant->nodeValue;
echo '<br>';
}
}
/*
* Output:
*
* bob - Bob Ultra Long Surname
* tom - Tom Ultra Long Surname
* tim - Tim Short
* leo - Leo Short
*/
// How to get "&cName;" instead of "Ultra Long Surname"?
答案 0 :(得分:0)
答案 1 :(得分:0)
DOM中的任何内容都是一个节点。您已经找到了实体定义,实体引用也是一个节点。但是,仅由于详细程度,在此级别上进行工作会很费力。 Xpath可以提供很多帮助。它允许您获取特定的节点。
要获取实体引用,您必须查看元素内的节点。
$xml = <<<'XML'
<?xml version="1.0"?>
<!DOCTYPE inhabitants [
<!ENTITY cName "Ultra Long Surname">
]>
<inhabitants>
<inhabitant alias="bob">Bob &cName;</inhabitant>
<inhabitant alias="tom">Tom &cName;</inhabitant>
<inhabitant alias="tim">Tim Short</inhabitant>
<inhabitant alias="leo">Leo Short</inhabitant>
</inhabitants>
XML;
$document = new DOMDocument;
$document->loadXML($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('//inhabitant') as $inhabitant) {
echo $inhabitant->getAttribute('alias');
echo ' - ';
foreach ($inhabitant->childNodes as $node) {
echo get_class($node), ": ";
if ($node instanceof DOMText) {
echo $node->textContent;
} elseif ($node instanceof DOMEntityReference) {
echo $node->nodeName;
}
}
echo "\n";
}
输出:
bob - DOMText: Bob DOMEntityReference: cName
tom - DOMText: Tom DOMEntityReference: cName
tim - DOMText: Tim Short
leo - DOMText: Leo Short
我不确定您要对数据库中的实体引用做什么。与文档断开连接将不会引用任何值。
可以使用Xpath完成在节点之前获取注释的操作
$xml = <<<'XML'
<?xml version="1.0"?>
<districts>
<district name="d1">
<street size="small">Nameless street</street>
<street size="long">Sutton Lane</street>
</district>
<district name="d2">
<!-- Not explored -->
<street size="unknown">Street of Death</street>
</district>
</districts>
XML;
$document = new DOMDocument;
$document->loadXML($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('//district/street') as $street) {
echo $street->textContent, ':';
echo $xpath->evaluate(
'string(preceding-sibling::node()[normalize-space(.) != ""][1][self::comment()])',
$street
);
echo "\n";
}
输出:
Nameless street:
Sutton Lane:
Street of Death: Not explored
preceding-sibling::node()[normalize-space(.) != ""]
preceding-sibling::node()[normalize-space(.) != ""][1]
preceding-sibling::node()[normalize-space(.) != ""][1][self::comment()]
string(preceding-sibling::node()[normalize-space(.) != ""][1][self::comment()])