英文:
How to get element count in multiple xml files in a folder using PHP?
问题
以下是翻译好的代码部分:
<?php
$doc = new DOMDocument;
$xml = simplexml_load_file("uploads/test.xml");
//file to SimpleXMLElement
$xml = simplexml_import_dom($xml);
print("Number of elements: ".$xml->count());
?>
英文:
The following php script gives count of elements in a single xml file in the folder uploads. But I have number of xml files in the folder. What to modify in the following script so that I get result in tabular format with the file name and element count for all the xml files in the folder.
<?php
$doc = new DOMDocument;
$xml = simplexml_load_file("uploads/test.xml");
//file to SimpleXMLElement
$xml = simplexml_import_dom($xml);
print("Number of elements: ".$xml->count());
?>
答案1
得分: 2
首先,创建一个带有你所拥有的逻辑的function
:
function getXML($path) {
$doc = new DOMDocument;
$xml = simplexml_load_file($path);
//将文件加载为SimpleXMLElement
$xml = simplexml_import_dom($xml);
return $xml;
}
请注意,我:
- 将路径转换为参数,这样你可以重复使用相同的逻辑来处理不同的文件
- 将XML的解析与显示分开
- 返回XML本身,这样你可以获取其计数或执行其他你可能想要的操作
这是如何获取给定路径的文件的方法:
$files = array_diff(scandir('uploads'), array('.', '..'));
我们获取了除了'.'
和'..'
之外的所有文件,这些文件肯定不会在这里感兴趣。了解更多关于scandir
的信息,请参考:https://www.php.net/manual/en/function.scandir.php
成功时,你会获得一个文件名的数组,因此,让我们循环它并执行你需要的逻辑:
$xmls = [];
foreach ($files as $file) {
if (str_ends_with($file, '.xml')) {
$xmls[] = $file . "\t" . getXML('uploads/' . $file)->count();
}
}
echo implode("\n", $xmls);
编辑
正如@Juan在评论部分友好地解释的那样,你可以使用以下代码:
$files = glob("./uploads/*.xml");
而不是使用scandir
,这将确保我们不再需要调用array_diff
,并且稍后可以避免在循环中使用if
:
$xmls = [];
foreach ($files as $file) {
$xmls[] = $file . "\t" . getXML('uploads/' . $file)->count();
}
echo implode("\n", $xmls);
英文:
First, create a function
with the logic you have:
function getXML($path) {
$doc = new DOMDocument;
$xml = simplexml_load_file($path);
//file to SimpleXMLElement
$xml = simplexml_import_dom($xml);
return $xml;
}
Note that I:
- have converted the path into a parameter, so you can reuse the same logic for your files
- separated the parsing of XML from showing it
- returned the XML itself, so you can get the count or you can do whatever else you may want with it
This is how you can get the files of a given path:
$files = array_diff(scandir('uploads'), array('.', '..'));
we get all files except for .
and ..
, which are surely not of interest here. Read more about scandir here: https://www.php.net/manual/en/function.scandir.php
You received an array of filenames on success, so, let's loop it and perform the logic you need:
$xmls = [];
foreach ($files as $file) {
if (str_ends_with($file, '.xml')) {
$xmls[] = $file . "\t" . getXML('uploads/' . $file)->count();
}
}
echo implode("\n", $xmls);
EDIT
As @Juan kindly explained in the comment section, one can use
$files = glob("./uploads/*.xml");
instead of scandir
and that would ensure that we no longer need a call for array_diff
and later we can avoid the if
inside the loop:
$xmls = [];
foreach ($files as $file) {
$xmls[] = $file . "\t" . getXML('uploads/' . $file)->count();
}
echo implode("\n", $xmls);
答案2
得分: 2
你首先将XML文件加载到一个SimpleXMLElement
中,然后导入到DOMElement
并调用其count()
方法。但是DOMElement
上并没有这个方法,只有SimpleXMLElement
上有。所以导入操作是不必要的。
你可以使用GlobIterator
来遍历文件:
$directory = __DIR__.'/uploads';
// 获取XML文件的迭代器
$files = new GlobIterator(
$directory.'/*.xml', FilesystemIterator::CURRENT_AS_FILEINFO
);
$results = [];
foreach ($files as $file) {
// 使用绝对文件路径加载文件
// 返回的SimpleXMLElement包装了文档元素节点
$documentElement = simplexml_load_file($file->getRealPath());
$results[] = [
// 文件名(不包含路径)
'file' => $file->getFilename(),
// "SimpleXMLElement::count()" 返回元素的子元素数量
'item-count' => $documentElement->count(),
];
}
var_dump($results);
使用DOM,你可以使用XPath从XML中提取特定的值:
$directory = __DIR__.'/uploads';
// 获取XML文件的迭代器
$files = new GlobIterator(
$directory.'/*.xml', FilesystemIterator::CURRENT_AS_FILEINFO
);
// 只需要一个文档实例
$document = new DOMDocument();
$results = [];
foreach ($files as $file) {
// 将文件加载到DOM文档中
$document->load($file->getRealPath());
// 为加载的文档创建XPath处理器
$xpath = new DOMXpath($document);
$results[] = [
'file' => $file->getFilename(),
// 使用XPath表达式来提取值
'item-count' => $xpath->evaluate('count(/*/*)'),
];
}
var_dump($results);
XPath表达式
- 获取文档元素
/*
- 获取文档元素的子元素
/*/*
- 计算它们的数量
count(/*/*)
*
是一个通用选择器,匹配任何元素节点。如果可能的话,应该更具体地使用实际的元素名称(例如 /list/item
)。
英文:
You're first loading the XML file into a SimpleXMLElement
then import it into a DOMElement
and call the method count()
on it. This method does not exists on DOMElement
- only on SimpleXMLElement
. So the import would not be necessary.
You can use a GlobIterator
to iterate the files:
$directory = __DIR__.'/uploads';
// get an iterator for the XML files
$files = new GlobIterator(
$directory.'/*.xml', FilesystemIterator::CURRENT_AS_FILEINFO
);
$results = [];
foreach ($files as $file) {
// load file using absolute file path
// the returned SimpleXMLElement wraps the document element node
$documentElement = simplexml_load_file($file->getRealPath());
$results[] = [
// file name without path
'file' => $file->getFilename(),
// "SimpleXMLElement::count()" returns the number of children of an element
'item-count' => $documentElement->count(),
];
}
var_dump($results);
With DOM you can use Xpath to fetch specific values from the XML.
$directory = __DIR__.'/uploads';
// get an iterator for the XML files
$files = new GlobIterator(
$directory.'/*.xml', FilesystemIterator::CURRENT_AS_FILEINFO
);
// only one document instance is needed
$document = new DOMDocument();
$results = [];
foreach ($files as $file) {
// load the file into the DOM document
$document->load($file->getRealPath());
// create an Xpath processor for the loaded document
$xpath = new DOMXpath($document);
$results[] = [
'file' => $file->getFilename(),
// use an Xpath expression to fetch the value
'item-count' => $xpath->evaluate('count(/*/*)'),
];
}
var_dump($results);
The Xpath Expression
- Get the document element
/*
- Get the child elements of the document element
/*/*
- Count them
count(/*/*)
*
is an universal selector for any element node. If you can you should be more specific and use the actual element names (e.g. /list/item
).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论