PHP - 如果每个记录的元素具有相似的标签,则获取正确的 XML 值
PHP - Fetch correct XML values if elements have similar tags per record
PHP - 如果每个记录的元素具有相似的标签
,则获取正确的 XML 值
我正在获取以下 xml 文件:
XML 文件:
<?xml version='1.0' encoding='UTF-8'?>
<abc:ABCData xmlns:abc="http://www.abc-example.com" xmlns:xyz="http:/www.xyz-example.com">
<abc:ABCRecords>
<abc:ABCRecord>
<abc:ABC>5EXZX4LPK</abc:ABC>
<abc:Entity>
<abc:Name>I Bornheim</abc:Name>
<abc:Periods>
<abc:Period>
<abc:Start>2017-01-01</abc:Start>
<abc:End>2017-12-31</abc:End>
<abc:Type>ACCOUNTING</abc:Type>
</abc:Period>
<abc:Period>
<abc:Start>2007-09-01</abc:Start>
<abc:Type>RELATIONSHIP</abc:Type>
</abc:Period>
</abc:Periods>
</abc:Entity>
</abc:ABCRecord>
<abc:ABCRecord>
<abc:ABC>5967007LI</abc:ABC>
<abc:Entity>
<abc:Name>SUN BANK</abc:Name>
<abc:Periods>
<abc:Period>
<abc:Start>2018-01-01</abc:Start>
<abc:End>2018-12-31</abc:End>
<abc:Type>BALANCED</abc:Type>
</abc:Period>
<abc:Period>
<abc:Start>2008-09-01</abc:Start>
<abc:Type>PARENT</abc:Type>
</abc:Period>
</abc:Periods>
</abc:Entity>
</abc:ABCRecord>
</abc:ABCRecords>
</abc:ABCData>
...使用此脚本,我将值输出为 csv:
PHP 文件:
<?php
$reader = new XMLReader();
$reader->open('php://stdin');
$output = fopen('php://stdout', 'w');
fputcsv($output, ['id', 'name']);
$xmlns = [
'abc' => 'http://www.abc-example.com'
];
$dom = new DOMDocument;
$xpath = new DOMXpath($dom);
foreach ($xmlns as $prefix => $namespaceURI) {
$xpath->registerNamespace($prefix, $namespaceURI);
}
while (
$reader->read() &&
(
$reader->localName !== 'ABCRecord' ||
$reader->namespaceURI !== $xmlns['abc']
)
) {
continue;
}
while ($reader->localName === 'ABCRecord') {
if ($reader->namespaceURI === 'http://www.abc-example.com') {
$node = $reader->expand($dom);
fputcsv(
$output,
[
$xpath->evaluate('string(abc:ABC)', $node),
$xpath->evaluate('string(abc:Entity/abc:Name)', $node)
]
);
}
$reader->next('ABCRecord');
}
...像这样:
输出:
5EXZX4LPK,"I Bornheim"
5967007LI,"SUN BANK"
但是...如果每个期间记录都具有相同的标签定义,我如何获取正确的 'period' 值?
期望的输出:
5EXZX4LPK,"I Bornheim",2017-01-01,2017-12-31,"ACCOUNTING",2007-09-01,"RELATIONSHIP"
5967007LI,"SUN BANK",2018-01-01,2018-12-31,"BALANCED",2008-09-01,"PARENT"
您可以简单地使用XPath 的索引表示法;将 <abc:Period>
元素视为数组中的元素。请记住,XPath 索引是从一开始的,而不是从零开始的。
...
fputcsv(
$output,
[
$xpath->evaluate('string(abc:ABC)', $node),
$xpath->evaluate('string(abc:Entity/abc:Name)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[1]/abc:Start)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[1]/abc:End)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[1]/abc:Type)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[2]/abc:Start)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[2]/abc:Type)', $node),
]
);
...
输出:
id,name
5EXZX4LPK,"I Bornheim",2017-01-01,2017-12-31,ACCOUNTING,2007-09-01,RELATIONSHIP
5967007LI,"SUN BANK",2018-01-01,2018-12-31,BALANCED,2008-09-01,PARENT
您可以使用该类型对句点进行分组并获取第一个分组结果:
$xpath->evaluate(
'string(
abc:Entity/abc:Periods/abc:Period[
abc:Type = "ACCOUNTING" or abc:Type="BALANCED"
][1]/abc:Type
)',
$node
),
或者你检查这里是否有一个 abc:End
子元素:
$xpath->evaluate(
'string(
abc:Entity/abc:Periods/abc:Period[
count(abc:End) = 0
][1]/abc:Type
)',
$node
),
PHP - 如果每个记录的元素具有相似的标签
,则获取正确的 XML 值我正在获取以下 xml 文件:
XML 文件:
<?xml version='1.0' encoding='UTF-8'?>
<abc:ABCData xmlns:abc="http://www.abc-example.com" xmlns:xyz="http:/www.xyz-example.com">
<abc:ABCRecords>
<abc:ABCRecord>
<abc:ABC>5EXZX4LPK</abc:ABC>
<abc:Entity>
<abc:Name>I Bornheim</abc:Name>
<abc:Periods>
<abc:Period>
<abc:Start>2017-01-01</abc:Start>
<abc:End>2017-12-31</abc:End>
<abc:Type>ACCOUNTING</abc:Type>
</abc:Period>
<abc:Period>
<abc:Start>2007-09-01</abc:Start>
<abc:Type>RELATIONSHIP</abc:Type>
</abc:Period>
</abc:Periods>
</abc:Entity>
</abc:ABCRecord>
<abc:ABCRecord>
<abc:ABC>5967007LI</abc:ABC>
<abc:Entity>
<abc:Name>SUN BANK</abc:Name>
<abc:Periods>
<abc:Period>
<abc:Start>2018-01-01</abc:Start>
<abc:End>2018-12-31</abc:End>
<abc:Type>BALANCED</abc:Type>
</abc:Period>
<abc:Period>
<abc:Start>2008-09-01</abc:Start>
<abc:Type>PARENT</abc:Type>
</abc:Period>
</abc:Periods>
</abc:Entity>
</abc:ABCRecord>
</abc:ABCRecords>
</abc:ABCData>
...使用此脚本,我将值输出为 csv:
PHP 文件:
<?php
$reader = new XMLReader();
$reader->open('php://stdin');
$output = fopen('php://stdout', 'w');
fputcsv($output, ['id', 'name']);
$xmlns = [
'abc' => 'http://www.abc-example.com'
];
$dom = new DOMDocument;
$xpath = new DOMXpath($dom);
foreach ($xmlns as $prefix => $namespaceURI) {
$xpath->registerNamespace($prefix, $namespaceURI);
}
while (
$reader->read() &&
(
$reader->localName !== 'ABCRecord' ||
$reader->namespaceURI !== $xmlns['abc']
)
) {
continue;
}
while ($reader->localName === 'ABCRecord') {
if ($reader->namespaceURI === 'http://www.abc-example.com') {
$node = $reader->expand($dom);
fputcsv(
$output,
[
$xpath->evaluate('string(abc:ABC)', $node),
$xpath->evaluate('string(abc:Entity/abc:Name)', $node)
]
);
}
$reader->next('ABCRecord');
}
...像这样:
输出:
5EXZX4LPK,"I Bornheim"
5967007LI,"SUN BANK"
但是...如果每个期间记录都具有相同的标签定义,我如何获取正确的 'period' 值?
期望的输出:
5EXZX4LPK,"I Bornheim",2017-01-01,2017-12-31,"ACCOUNTING",2007-09-01,"RELATIONSHIP"
5967007LI,"SUN BANK",2018-01-01,2018-12-31,"BALANCED",2008-09-01,"PARENT"
您可以简单地使用XPath 的索引表示法;将 <abc:Period>
元素视为数组中的元素。请记住,XPath 索引是从一开始的,而不是从零开始的。
...
fputcsv(
$output,
[
$xpath->evaluate('string(abc:ABC)', $node),
$xpath->evaluate('string(abc:Entity/abc:Name)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[1]/abc:Start)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[1]/abc:End)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[1]/abc:Type)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[2]/abc:Start)', $node),
$xpath->evaluate('string(abc:Entity/abc:Periods/abc:Period[2]/abc:Type)', $node),
]
);
...
输出:
id,name
5EXZX4LPK,"I Bornheim",2017-01-01,2017-12-31,ACCOUNTING,2007-09-01,RELATIONSHIP
5967007LI,"SUN BANK",2018-01-01,2018-12-31,BALANCED,2008-09-01,PARENT
您可以使用该类型对句点进行分组并获取第一个分组结果:
$xpath->evaluate(
'string(
abc:Entity/abc:Periods/abc:Period[
abc:Type = "ACCOUNTING" or abc:Type="BALANCED"
][1]/abc:Type
)',
$node
),
或者你检查这里是否有一个 abc:End
子元素:
$xpath->evaluate(
'string(
abc:Entity/abc:Periods/abc:Period[
count(abc:End) = 0
][1]/abc:Type
)',
$node
),