繁体   English   中英

使用命名空间显示 xml 值 - 使用 php

[英]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);
    }
}

Output

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM