[英]Display xml values with namespace - using php
我想知道如何从返回 xml 的 api 中显示这些值。我查看了一些地方,但它总是一个没有命名空间,而另一些有命名空间……但我的两者都有,而且总是有错误并且不显示值..
我的 xml:
<QTableGridDataSourceForMobileOfDocumentWBuH9k12 xmlns="http://schemas.datacontract.org/2004/07/Sinfic.DataContracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<TotalRows>1</TotalRows>
<Rows xmlns:a="http://schemas.datacontract.org/2004/07/Sinfic.DataContracts.Documents">
<a:Document>
<a:a>6017</a:a>
<a:aa>135</a:aa>
<a:ab>-23.15749833</a:ab>
<a:ac>-45.79356167</a:ac>
<a:ad>6.80</a:ad>
<a:ai>0</a:ai>
<a:aj>Administrator</a:aj>
<a:am>32872</a:am>
<a:an>Leonardo Righi</a:an>
<a:ao>16470252</a:ao>
<a:ap>16470108</a:ap>
<a:aq>
<a:data>
<a:key>
<a:id>d0180056-f7e6-4b13-8865-a963a9a131</a:id>
<a:tag>nomeTecnico</a:tag>
</a:key>
<a:value>Denis Rodrigues</a:value>
</a:data>
<a:ar>
<a:data>
<a:key>
<a:id>d6052d01-92b3-45a5-9059-f401eddf0ef5</a:id>
<a:tag>ImageAnswer</a:tag>
</a:key>
<a:value>27422</a:value>
</a:data>
</a:ar>
<a:b>150</a:b>
<a:bb>Manutenção Automáticas</a:bb>
<a:bc>02 - CELULARES</a:bc>
<a:bd>Cancelado</a:bd>
<a:bf>09/03/2022 14:52</a:bf>
<a:bg>11/03/2022 15:00</a:bg>
<a:bh>Automaticas</a:bh>
<a:bi>5</a:bi>
<a:bj>09/03/2022 14:41</a:bj>
<a:bk>09/03/2022 14:52</a:bk>
<a:bq>LOGISTICA LTDA</a:bq>
<a:br>2</a:br>
<a:bs>2</a:bs>
<a:bt>false</a:bt>
<a:bu>MyDocs</a:bu>
<a:bv># 1.4.17[14017]</a:bv>
<a:by>f1edqKgAgFWvOHGTmEFw42uggIDQt-K8pKPFaC6Em-Z7etzLOSr3Al6eCPndbg2</a:by>
<a:cd>656</a:cd>
<a:ce>13235</a:ce>
<a:l>DENIS </a:l>
<a:o>f8b521e8-e92f-478e-a883</a:o>
</a:Document>
</Rows>
</QTableGridDataSourceForMobileOfDocumentWBuH9k12>
我尽可能接近地尝试了这段代码:
<?php
$x = simplexml_load_file('teste.xml');
$campos = $x->
children('a', true)->
children('a', true);
foreach($campos as $chave => $valor){
echo $chave.' : '. $valor . '<br>';
}
?>
您可以通过提供命名空间或其前缀来访问子项。 我更喜欢前缀,因为它更短。
演示(上一个): https://3v4l.org/VNt5d
演示(递归): https://3v4l.org/uelMs
您的数据仍然无效。 <a:aq>
未关闭。 所以我删除了它作为我的答案!
$xml = simplexml_load_string($xmlText);
function printKeyValue(string $key, SimpleXMLElement $value): void {
echo "$key: ";
if ($children = $value->children('a', true)) {
foreach($children as $childKey => $childValue) {
printKeyValue($childKey, $childValue);
}
return;
}
echo "$value\n";
};
foreach($xml->Rows->children('a', true) as $document) {
foreach($document as $key => $value) {
printKeyValue($key, $value);
}
}
a: 6017
aa: 135
ab: -23.15749833
ac: -45.79356167
ad: 6.80
ai: 0
aj: Administrator
am: 32872
an: Leonardo Righi
ao: 16470252
ap: 16470108
data: key: id: d0180056-f7e6-4b13-8865-a963a9a131
tag: nomeTecnico
value: Denis Rodrigues
ar: data: key: id: d6052d01-92b3-45a5-9059-f401eddf0ef5
tag: ImageAnswer
value: 27422
b: 150
bb: Manutenção Automáticas
bc: 02 - CELULARES
bd: Cancelado
bf: 09/03/2022 14:52
bg: 11/03/2022 15:00
bh: Automaticas
bi: 5
bj: 09/03/2022 14:41
bk: 09/03/2022 14:52
bq: LOGISTICA LTDA
br: 2
bs: 2
bt: false
bu: MyDocs
bv: # 1.4.17[14017]
by: f1edqKgAgFWvOHGTmEFw42uggIDQt-K8pKPFaC6Em-Z7etzLOSr3Al6eCPndbg2
cd: 656
ce: 13235
l: DENIS
o: f8b521e8-e92f-478e-a883
您将名称空间前缀误认为是实际的名称空间。 名称空间定义是xmlns
/ xmlns:*
属性。 元素节点的前缀是可选的。 文档元素应读作{http://schemas.datacontract.org/2004/07/Sinfic.DataContracts}QTableGridDataSourceForMobileOfDocumentWBuH9k12
。 这里有 3 个例子,都解决了这个问题:
<QTableGridDataSourceForMobileOfDocumentWBuH9k12 xmlns="http://schemas.datacontract.org/2004/07/Sinfic.DataContracts">
<q:QTableGridDataSourceForMobileOfDocumentWBuH9k12 xmlns:q="http://schemas.datacontract.org/2004/07/Sinfic.DataContracts">
<qtable:QTableGridDataSourceForMobileOfDocumentWBuH9k12 xmlns:qtable="http://schemas.datacontract.org/2004/07/Sinfic.DataContracts">
命名空间可以在任何元素节点上重新定义。 所以前缀只有在重新定义之前才有效。 这使得依赖文档中的前缀成为一个非常糟糕的主意。 始终使用名称空间 URI 和/或定义您自己的前缀。
SimpleXML 在后台进行一些隐式命名空间处理——比如使用当前上下文节点的默认命名空间。 显式变体如下所示:
const XMLNS_CONTRACTS = 'http://schemas.datacontract.org/2004/07/Sinfic.DataContracts';
const XMLNS_DOCUMENT = 'http://schemas.datacontract.org/2004/07/Sinfic.DataContracts.Documents';
$qTable = simplexml_load_string(getXMLString());
foreach($qTable->children(XMLNS_CONTRACTS)->Rows->children(XMLNS_DOCUMENT) as $document) {
foreach($document as $key => $value) {
var_dump([$key, (string)$value]);
}
}
或者使用 DOM 和 Xpath:
请注意,该示例对 Xpath 表达式使用了自己的前缀。 它仅取决于名称空间 URI。
const XMLNS_CONTRACTS = 'http://schemas.datacontract.org/2004/07/Sinfic.DataContracts';
const XMLNS_DOCUMENT = 'http://schemas.datacontract.org/2004/07/Sinfic.DataContracts.Documents';
$document = new DOMDocument();
$document->loadXML(getXMLString());
$xpath = new DOMXpath($document);
$xpath->registerNamespace('c', XMLNS_CONTRACTS);
$xpath->registerNamespace('d', XMLNS_DOCUMENT);
foreach ($xpath->evaluate('//c:Rows/d:Document') as $rowsDocument) {
foreach($xpath->evaluate('./d:*', $rowsDocument) as $cell) {
var_dump(
[$cell->localName, $cell->textContent]
);
}
}
恕我直言,XML 格式不是一个好的格式 - 因此使用起来可能会让人觉得烦人。 XML 标签应该是固定的和语义的。 动态标签名字很大没有go。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.