我有一个简单的XML文档:
<?xml version="1.0"?>
<cellphones>
<telefon>
<model>Easy DB</model>
<proizvodjac>Alcatel</proizvodjac>
<cena>25</cena>
</telefon>
<telefon>
<model>3310</model>
<proizvodjac>Nokia</proizvodjac>
<cena>30</cena>
</telefon>
<telefon>
<model>GF768</model>
<proizvodjac>Ericsson</proizvodjac>
<cena>15</cena>
</telefon>
<telefon>
<model>Skeleton</model>
<proizvodjac>Panasonic</proizvodjac>
<cena>45</cena>
</telefon>
<telefon>
<model>Earl</model>
<proizvodjac>Sharp</proizvodjac>
<cena>60</cena>
</telefon>
</cellphones>
Run Code Online (Sandbox Code Playgroud)
我需要使用XML DOM打印此文件的内容,它需要像这样构造:
"model: Easy DB
proizvodjac: Alcatel
cena: 25"
Run Code Online (Sandbox Code Playgroud)
对于XML中的每个节点.
它必须使用XML DOM完成.那就是问题所在.我可以通常,简单的方式做到这一点.但是这个让我烦恼,因为我似乎无法在互联网上找到任何解决方案.
这是我可以做的,但我需要访问内部节点(子节点)并获取节点值.我也想摆脱一些奇怪的字符串"#text",它出现了.
<?php
//kreira se DOMDocument objekat
$xmlDoc = new DOMDocument();
//u xml objekat se ucitava xml fajl
$xmlDoc->load("poruke.xml");
//dodeljuje se promenljivoj koreni element
$x = $xmlDoc->documentElement;
//prolazi se kroz petlju tako sto se ispisuje informacija o podelementima
foreach ($x->childNodes AS $item){
print $item->nodeName . " = " . $item->nodeValue . "<br />";
}
?>
Run Code Online (Sandbox Code Playgroud)
谢谢
对奇怪的#text字符串的解释
奇怪的#text字符串不是蓝色的,而是实际的文本节点.当您使用DOM任何空格加载带格式的XML文档时,例如缩进,换行符和节点值将DOMText默认为DOM的一部分,例如
<cellphones>\n\t<telefon>\n\t\t<model>Easy DB…
E T E T E T
Run Code Online (Sandbox Code Playgroud)
其中E是a DOMElement而T是a DOMText.
要解决这个问题,请加载文档,如下所示:
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->load('file.xml');
Run Code Online (Sandbox Code Playgroud)
然后您的文档结构如下
<cellphones><telefon><model>Easy DB…
E E E T
Run Code Online (Sandbox Code Playgroud)
请注意,表示a值的各个节点DOMElement仍然是DOMText实例,但控制格式化的节点消失了.稍后会详细介绍.
证明
您可以使用以下代码轻松测试:
$dom = new DOMDocument;
$dom->preserveWhiteSpace = TRUE; // change to FALSE to see the difference
$dom->load('file.xml');
foreach ($dom->getElementsByTagName('telefon') as $telefon) {
foreach($telefon->childNodes as $node) {
printf(
"Name: %s - Type: %s - Value: %s\n",
$node->nodeName,
$node->nodeType,
urlencode($node->nodeValue)
);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码遍历给定XML中的所有telefon元素,并打印出节点名称,类型及其子节点的urlencoded节点值.当你保留空格时,你会得到类似的东西
Name: #text - Type: 3 - Value: %0A++++
Name: model - Type: 1 - Value: Easy+DB
Name: #text - Type: 3 - Value: %0A++++
Name: proizvodjac - Type: 1 - Value: Alcatel
Name: #text - Type: 3 - Value: %0A++++
Name: cena - Type: 1 - Value: 25
Name: #text - Type: 3 - Value: %0A++
…
Run Code Online (Sandbox Code Playgroud)
我对该值进行了urlencoding的原因是为了表明实际上存在DOMText包含缩进和行间断的节点DOMDocument.%0A是一个换行符,而每个+都是一个空格.
当您将其与XML进行比较时,您将看到在每个<telefon>元素之后有一个换行符后跟四个空格,直到<model>元素开始.同样,在收盘<cena>和开盘之间只有一个换行符和两个空格<telefon>.
这些节点的给定类型是3,根据预定义常量列表,它是XML_TEXT_NODE例如DOMText节点.由于缺少适当的元素名称,这些节点的名称为#text.
无视空白
现在,当你禁用空白的保存时,上面会输出:
Name: model - Type: 1 - Value: Easy+DB
Name: proizvodjac - Type: 1 - Value: Alcatel
Name: cena - Type: 1 - Value: 25
Name: model - Type: 1 - Value: 3310
…
Run Code Online (Sandbox Code Playgroud)
如您所见,不再有#text节点,而只有类型1节点,这意味着XML_ELEMENT_NODE,例如DOMElement.
DOMElements包含DOMText节点
在开头我说过,值DOMElements也是DOMText实例.但在上面的输出中,它们无处可见.那是因为我们正在访问nodeValue属性,该属性返回DOMTextas字符串的值.我们可以证明价值很DOMText容易:
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xml);
foreach ($dom->getElementsByTagName('telefon') as $telefon) {
$node = $telefon->firstChild->firstChild; // 1st child of model
printf(
"Name: %s - Type: %s - Value: %s\n",
$node->nodeName,
$node->nodeType,
urlencode($node->nodeValue)
);
}
Run Code Online (Sandbox Code Playgroud)
将输出
Name: #text - Type: 3 - Value: Easy+DB
Name: #text - Type: 3 - Value: 3310
Name: #text - Type: 3 - Value: GF768
Name: #text - Type: 3 - Value: Skeleton
Name: #text - Type: 3 - Value: Earl
Run Code Online (Sandbox Code Playgroud)
这证明了DOMElement它包含它的价值,DOMText并且nodeValue只是DOMText直接返回内容.
有关nodeValue的更多信息
事实上,nodeValue聪明到足以连接任何DOMText孩子的内容:
$dom = new DOMDocument;
$dom->loadXML('<root><p>Hello <em>World</em>!!!</p></root>');
$node = $dom->documentElement->firstChild; // p
printf(
"Name: %s - Type: %s - Value: %s\n",
$node->nodeName,
$node->nodeType,
$node->nodeValue
);
Run Code Online (Sandbox Code Playgroud)
将输出
Name: p - Type: 1 - Value: Hello World!!!
Run Code Online (Sandbox Code Playgroud)
虽然这些是真正的综合价值
DOMText "Hello"
DOMElement em with DOMText "World"
DOMText "!!!"
Run Code Online (Sandbox Code Playgroud)
使用XML DOM打印XML文件的内容
要最终回答您的问题,请查看第一个测试代码.你需要的一切都在那里.当然,到目前为止,你也得到了很好的其他答案.