使用 PHP 替换 xml/plist 文件中的字符串
Replacing a string in an xml/plist file using PHP
我在一个目录中有两个 .plist
文件,它们看起来都像这样:
<dict>
<key>bundle-identifier</key>
<string>TEXT</string>
<key>bundle-version</key>
<string>VESRION</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>TEXT</string>
<key>title</key>
<string>TEXT</string>
</dict>
我得到了标题的value/string:
$files = array();
foreach (glob("../../plists/*.plist") as $file) {
$files[] = $file;
//echo "$file";
$fileContent = file_get_contents($file);
$xml = simplexml_load_string($fileContent) or die("Error: Cannot create object");
$resultNames = $xml->dict->array->dict->dict->string[4] . '<br /> <br />';
//echo $resultNames;
}
现在我想用 php 更改 title 的 value/string,就像我更改 title 一样 value/string 其中一个我不希望另一个受到影响,可以吗?
我不确定是否理解所有内容,但您可以使用 DomDocument 更改值。
$doc = new DOMDocument;
$doc->load('your_xml_file.xml');
$elements = $doc->getElementsByTagName("string");
foreach ($elements as $element) {
//$element->nodeName will be "string"
$nodes = $element->childNodes;
foreach ($nodes as $node) {
$node->nodeValue = 'New value';
}
}
$doc->save("newfile.xml")
不确定标题的回显是如何工作的,但在这段代码中,我使用 XPath 找到了内容为 title
的 <key>
元素。然后它获取以下 <string>
元素的值。
要更新它,您可以在 SimpleXML 中稍作改动,使其设置 <string>
元素的值,然后将结果 XML 保存回同一个文件姓名....
$xml = simplexml_load_string($fileContent) or die("Error: Cannot create object");
// Find the correct string element from the preceding key for title
$titleString = $xml->xpath('//key[.="title"]/following-sibling::string')[0];
// Set new value
$titleString[0] = "new Title1";
// Save the file
$xml->asXML($file);
如果你通过文件名识别内容,那么检查$file
,但如果你只能通过标题识别它,那么你需要检查是否找到你想要的标题。
$titleToUpdate = "Correct Title2";
$fileContent = file_get_contents($file);
$xml = simplexml_load_string($fileContent) or die("Error: Cannot create object");
$titleString = $xml->xpath('//key[.="title"]/following-sibling::string[.="'.$titleToUpdate.'"]');
// Check there is 1 matching item
if ( count($titleString) == 1 ) {
$titleString[0][0] = "new Title12";
$xml->asXML($file);
}
虽然不漂亮,但很管用。
$doc = new DOMDocument;
$doc->load('file_address');
$elements = $doc->documentElement;
$found = false;
foreach ($elements->childNodes AS $item) {
if($found){
$item->nodeValue = 'changed';
$found = false;
}else{
if($item->nodeName == 'key' && $item->nodeValue == 'title'){
$found = true;
}
}
}
$doc->saveXML();
也可以将 Xpath 与 DOM 一起使用。
$titleToUpdate = 'Original Title';
$document = new DOMDocument();
// load from string, for file: $document->load($fileName);
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$expression = '//dict/key[.="title"]/following-sibling::string[.="'.$titleToUpdate.'"]';
$modified = FALSE;
foreach ($xpath->evaluate($expression) as $titleValueNode) {
$titleValueNode->textContent = 'Changed Title';
$modified = TRUE;
}
if ($modified) {
// output string, to save file: $document->save($fileName);
echo $document->saveXML();
}
输出:
<?xml version="1.0"?>
<dict>
<key>bundle-identifier</key>
<string>TEXT</string>
<key>bundle-version</key>
<string>VESRION</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>TEXT</string>
<key>title</key>
<string>Changed Title</string>
</dict>
这种方法会改变任何匹配的项目,并且只存储它修改的一个或多个。
现在,如果您确实需要为此查找不同的文件,我建议您将操作移动到一个函数中。
function replaceTitle(string $fileName, string $title): bool {
// the actual action from the example
return $modified;
}
$files = new GlobIterator(__DIR__.'/path/*.plist');
foreach ($files as $file) {
if (replaceTitle((string)$file, 'Original Title')) {
echo "Modified: $file\n";
}
}
我在一个目录中有两个 .plist
文件,它们看起来都像这样:
<dict>
<key>bundle-identifier</key>
<string>TEXT</string>
<key>bundle-version</key>
<string>VESRION</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>TEXT</string>
<key>title</key>
<string>TEXT</string>
</dict>
我得到了标题的value/string:
$files = array();
foreach (glob("../../plists/*.plist") as $file) {
$files[] = $file;
//echo "$file";
$fileContent = file_get_contents($file);
$xml = simplexml_load_string($fileContent) or die("Error: Cannot create object");
$resultNames = $xml->dict->array->dict->dict->string[4] . '<br /> <br />';
//echo $resultNames;
}
现在我想用 php 更改 title 的 value/string,就像我更改 title 一样 value/string 其中一个我不希望另一个受到影响,可以吗?
我不确定是否理解所有内容,但您可以使用 DomDocument 更改值。
$doc = new DOMDocument;
$doc->load('your_xml_file.xml');
$elements = $doc->getElementsByTagName("string");
foreach ($elements as $element) {
//$element->nodeName will be "string"
$nodes = $element->childNodes;
foreach ($nodes as $node) {
$node->nodeValue = 'New value';
}
}
$doc->save("newfile.xml")
不确定标题的回显是如何工作的,但在这段代码中,我使用 XPath 找到了内容为 title
的 <key>
元素。然后它获取以下 <string>
元素的值。
要更新它,您可以在 SimpleXML 中稍作改动,使其设置 <string>
元素的值,然后将结果 XML 保存回同一个文件姓名....
$xml = simplexml_load_string($fileContent) or die("Error: Cannot create object");
// Find the correct string element from the preceding key for title
$titleString = $xml->xpath('//key[.="title"]/following-sibling::string')[0];
// Set new value
$titleString[0] = "new Title1";
// Save the file
$xml->asXML($file);
如果你通过文件名识别内容,那么检查$file
,但如果你只能通过标题识别它,那么你需要检查是否找到你想要的标题。
$titleToUpdate = "Correct Title2";
$fileContent = file_get_contents($file);
$xml = simplexml_load_string($fileContent) or die("Error: Cannot create object");
$titleString = $xml->xpath('//key[.="title"]/following-sibling::string[.="'.$titleToUpdate.'"]');
// Check there is 1 matching item
if ( count($titleString) == 1 ) {
$titleString[0][0] = "new Title12";
$xml->asXML($file);
}
虽然不漂亮,但很管用。
$doc = new DOMDocument;
$doc->load('file_address');
$elements = $doc->documentElement;
$found = false;
foreach ($elements->childNodes AS $item) {
if($found){
$item->nodeValue = 'changed';
$found = false;
}else{
if($item->nodeName == 'key' && $item->nodeValue == 'title'){
$found = true;
}
}
}
$doc->saveXML();
也可以将 Xpath 与 DOM 一起使用。
$titleToUpdate = 'Original Title';
$document = new DOMDocument();
// load from string, for file: $document->load($fileName);
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$expression = '//dict/key[.="title"]/following-sibling::string[.="'.$titleToUpdate.'"]';
$modified = FALSE;
foreach ($xpath->evaluate($expression) as $titleValueNode) {
$titleValueNode->textContent = 'Changed Title';
$modified = TRUE;
}
if ($modified) {
// output string, to save file: $document->save($fileName);
echo $document->saveXML();
}
输出:
<?xml version="1.0"?>
<dict>
<key>bundle-identifier</key>
<string>TEXT</string>
<key>bundle-version</key>
<string>VESRION</string>
<key>kind</key>
<string>software</string>
<key>subtitle</key>
<string>TEXT</string>
<key>title</key>
<string>Changed Title</string>
</dict>
这种方法会改变任何匹配的项目,并且只存储它修改的一个或多个。
现在,如果您确实需要为此查找不同的文件,我建议您将操作移动到一个函数中。
function replaceTitle(string $fileName, string $title): bool {
// the actual action from the example
return $modified;
}
$files = new GlobIterator(__DIR__.'/path/*.plist');
foreach ($files as $file) {
if (replaceTitle((string)$file, 'Original Title')) {
echo "Modified: $file\n";
}
}