我正在練習 XML DOM PHP 決議。我有這樣的 XML 檔案(較短的版本):
<?xml version="1.0" encoding="UTF-8"?>
<tabela_kursow typ="A" uid="21a184">
<numer_tabeli>184/A/NBP/2021</numer_tabeli>
<data_publikacji>2021-09-22</data_publikacji>
<pozycja>
<nazwa_waluty>bat (Tajlandia)</nazwa_waluty>
<przelicznik>1</przelicznik>
<kod_waluty>THB</kod_waluty>
<kurs_sredni>0,1181</kurs_sredni>
</pozycja>
<pozycja>
<nazwa_waluty id="2">dolar amerykański</nazwa_waluty>
<przelicznik>1</przelicznik>
<kod_waluty>USD</kod_waluty>
<kurs_sredni>3,9460</kurs_sredni>
</pozycja>
</tabela_kursow>
我為兩個 Tag 元素創建了名稱為“id”且值為“2”的屬性。
<?php
$doc = new DOMDocument();
$doc->load("kursy_walut.xml");
$doc->preserveSpace = false;
$doc->formatOutput = true;
$a = $doc->getElementsByTagName("nazwa_waluty");
$b = count($a);
for ($i=0; $i<$b; $i ){
$c = $a[$i]->childNodes[0]->nodeValue;
if ($c === 'dolar amerykański'){
$a[$i]->setAttribute('id', '2');
}
if ($c === 'euro'){
$a[$i]->setAttribute('id', '2');
}
}
$doc->save('output.xml');
現在我想:
- 僅獲取不包含屬性 'id="2"' 的Tag 元素;
- 僅獲取僅包含'id="2"' 的Tag 元素。
對于第一種情況,我創建了這樣的代碼。不知道如何創建第二個案例。
$doc3 = new DOMDocument();
$doc3->preserveWhiteSpace = false;
$doc3->load('output.xml');
$xpath2 = new DOMXPath($doc3);
$id3 = $xpath2->query('//*/pozycja/nazwa_waluty[@id="2"]');
foreach($id3 as $attr){
$attr->parentNode->removeChild($attr);
}
$doc3->formatOutput = true;
$doc3->save('output3.xml');
也許有人可以幫助我解決第二種情況?謝謝你。
uj5u.com熱心網友回復:
如果我了解您的來源,那么您想根據貨幣字串添加一個 id。但是,您使用的是特定于語言的字串。語言代碼將是更好的選擇。它已經被定義并且是獨一無二的。
DOMNode::getElementsByTagName()回傳一個節點串列,你可以foreach用來迭代它。但是節點串列是“LIVE”。它對節點上的變化做出反應。如果您添加/洗掉節點,這是一個問題。使用 Xpath 運算式可以避免這種情況并允許進行更具體的提取。
更重要的是,看看DOMNode::$textContent屬性。它讀取/寫入節點內的整個文本。對于元素,這包括任何后代文本節點。
使用它可以簡化代碼:
$document = new DOMDocument();
// configure the parser - need to be set before load
$document->preserveWhiteSpace = false;
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$currencyMap = [
"USD" => 2,
"EUR" => 4
];
// iterate the "nazwa_waluty" elements
foreach ($xpath->evaluate('//pozycja/kod_waluty') as $kodWaluty) {
// get the currency code
$currencyCode = trim($kodWaluty->textContent);
if (isset($currencyMap[$currencyCode])) {
// add id for currency
$kodWaluty->setAttribute('id', $currencyMap[$currencyCode]);
}
}
// configure the serializer - need to be set before save
$document->formatOutput = true;
echo $document->saveXML();
輸出:
<?xml version="1.0" encoding="UTF-8"?>
<tabela_kursow typ="A" uid="21a184">
<numer_tabeli>184/A/NBP/2021</numer_tabeli>
<data_publikacji>2021-09-22</data_publikacji>
<pozycja>
<nazwa_waluty>bat (Tajlandia)</nazwa_waluty>
<przelicznik>1</przelicznik>
<kod_waluty>THB</kod_waluty>
<kurs_sredni>0,1181</kurs_sredni>
</pozycja>
<pozycja>
<nazwa_waluty>dolar amerykański</nazwa_waluty>
<przelicznik>1</przelicznik>
<kod_waluty id="2">USD</kod_waluty>
<kurs_sredni>3,9460</kurs_sredni>
</pozycja>
</tabela_kursow>
現在獲取具有特定 id 的資料。我希望你會想要pozycja元素及其子元素。
DOMXpath::evaluate()不僅可以回傳節點串列,還可以回傳標量值。沒有那么多代碼:
foreach ($xpath->evaluate('//pozycja[kod_waluty/@id = "2"]') as $pozycja) {
var_dump(
[
'przelicznik' => $xpath->evaluate('string(przelicznik)', $pozycja),
'kurs_sredni' => $xpath->evaluate('string(kurs_sredni)', $pozycja),
]
);
}
輸出:
array(2) {
["przelicznik"]=>
string(1) "1"
["kurs_sredni"]=>
string(6) "3,9460"
}
但是因為語言代碼已經定義并且是唯一的,你可以直接使用它:
foreach ($xpath->evaluate('//pozycja[normalize-space(kod_waluty) = "USD"]') as $pozycja) {
var_dump(
[
'przelicznik' => $xpath->evaluate('string(przelicznik)', $pozycja),
'kurs_sredni' => $xpath->evaluate('string(kurs_sredni)', $pozycja),
]
);
}
如果您需要特定貨幣代碼的“kurs_serdni”內容,那么您可以使用單個 Xpath 運算式執行此操作:
var_dump(
$xpath->evaluate(
'string(//pozycja[normalize-space(kod_waluty) = "USD"]/kurs_sredni)'
)
);
輸出:
string(6) "3,9460"
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318158.html
上一篇:HTML Javascript:無法一次從兩個元素中獲取所有實體?
下一篇:如何在特定類中定位id?
