我是使用DOM和PHP的新手,需要一些帮助来找出迭代xpath到数组的解决方案。我在网上找到的例子提供的帮助很少。
这是我的XML文件中的字符串内容:
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.2-c004 1.136881, 2010/06/10-18:11:35 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description
rdf:about=""
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
xmlns:exif="http://ns.adobe.com/exif/1.0/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"
xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/"
photoshop:LegacyIPTCDigest="B0D1E9B9CFC1C774E7277517B04970DC"
photoshop:ColorMode="3"
photoshop:ICCProfile="sRGB IEC61966-2.1"
photoshop:AuthorsPosition="Tester"
photoshop:Headline="Big City Landscape"
photoshop:CaptionWriter="Freelancer"
photoshop:DateCreated="2016-08-05T02:16Z"
photoshop:City="NA"
photoshop:State="NA"
photoshop:Country="NA"
photoshop:TransmissionReference="2323"
photoshop:Instructions="set to landscape"
photoshop:Credit="Photographor: FirstName lastname"
photoshop:Source="Smart Phone Photo"
tiff:Make="Motorola"
tiff:Model="MB865"
tiff:Orientation="1"
tiff:ImageWidth="3264"
tiff:ImageLength="1840"
tiff:PhotometricInterpretation="2"
tiff:SamplesPerPixel="3"
tiff:XResolution="72/1"
tiff:YResolution="72/1"
tiff:ResolutionUnit="2"
exif:ExifVersion="0220"
exif:ExposureTime="1/11"
exif:ShutterSpeedValue="3459432/1000000"
exif:FNumber="24/10"
exif:ApertureValue="2526069/1000000"
exif:ExposureProgram="0"
exif:BrightnessValue="0/1"
exif:ExposureBiasValue="0/10"
exif:MaxApertureValue="3/1"
exif:SubjectDistance="0/1"
exif:MeteringMode="1"
exif:LightSource="4"
exif:FocalLength="460/100"
exif:SceneType="1"
exif:CustomRendered="1"
exif:ExposureMode="0"
exif:WhiteBalance="0"
exif:SceneCaptureType="0"
exif:GainControl="256"
exif:Contrast="0"
exif:Saturation="0"
exif:Sharpness="0"
exif:SubjectDistanceRange="0"
exif:DigitalZoomRatio="65536/65535"
exif:PixelXDimension="3264"
exif:PixelYDimension="1840"
exif:ColorSpace="1"
xmp:ModifyDate="2016-02-22T09:22:39-05:00"
xmp:MetadataDate="2016-08-05T02:21:35-04:00"
aux:ApproximateFocusDistance="0/1"
crs:AlreadyApplied="True"
Iptc4xmpCore:IntellectualGenre="NA"
Iptc4xmpCore:Location="NA"
Iptc4xmpCore:CountryCode="NA">
<dc:rights>
<rdf:Alt>
<rdf:li xml:lang="x-default">Copyright FirstName lastname</rdf:li>
</rdf:Alt>
</dc:rights>
<dc:creator>
<rdf:Seq>
<rdf:li>FirstName lastname</rdf:li>
</rdf:Seq>
</dc:creator>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default">Jurks on the move</rdf:li>
</rdf:Alt>
</dc:description>
<dc:subject>
<rdf:Bag>
<rdf:li>New Jurks in Town</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default">Big City Jurks</rdf:li>
</rdf:Alt>
</dc:title>
<tiff:BitsPerSample>
<rdf:Seq>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
<rdf:li>8</rdf:li>
</rdf:Seq>
</tiff:BitsPerSample>
<exif:ISOSpeedRatings>
<rdf:Seq>
<rdf:li>107</rdf:li>
</rdf:Seq>
</exif:ISOSpeedRatings>
<exif:Flash exif:Fired="True" exif:Return="0" exif:Mode="1" exif:Function="False" exif:RedEyeMode="False"/>
<Iptc4xmpCore:CreatorContactInfo
Iptc4xmpCore:CiAdrExtadr=""
Iptc4xmpCore:CiAdrCity=""
Iptc4xmpCore:CiAdrRegion="NY"
Iptc4xmpCore:CiAdrPcode=""
Iptc4xmpCore:CiAdrCtry="USA"
Iptc4xmpCore:CiTelWork=""
Iptc4xmpCore:CiEmailWork="you@yourwebsite.com"
Iptc4xmpCore:CiUrlWork="www.yourwebsite.com"/>
<Iptc4xmpCore:SubjectCode>
<rdf:Bag>
<rdf:li>Jurks</rdf:li>
</rdf:Bag>
</Iptc4xmpCore:SubjectCode>
<Iptc4xmpCore:Scene>
<rdf:Bag>
<rdf:li>Big City</rdf:li>
</rdf:Bag>
</Iptc4xmpCore:Scene>
<xmpRights:UsageTerms>
<rdf:Alt>
<rdf:li xml:lang="x-default">Free to use</rdf:li>
</rdf:Alt>
</xmpRights:UsageTerms>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
这就是我解决问题的方法。
$__data = "xmp-cache-test.xml";
$content = file_get_contents('xmp-cache-test.xml');
if(preg_match("/(\<x\:xmpmeta.*?\>.*?\<\/x\:xmpmeta\>)/s", $content, $matches))
$data = "<?xml version='1.0'?>\n" . $matches[1];
$myXmlString = $data ;
$myXmlFilename = $__data;
$doc = new DOMDocument();
$doc->loadXML($myXmlString);
$doc->documentURI = $myXmlFilename;
$xpath = new DOMXpath($doc);
$xpath->registerNamespace('x', 'adobe:ns:meta/');
$xpath->registerNamespace('xmp', 'http://ns.adobe.com/xap/1.0/');
$xpath->registerNamespace("Iptc4xmpCore", "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/");
$xpath->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
$elements = $xpath->evaluate('//rdf:RDF/rdf:Description');
$arr_xmp = iterator_to_array($elements);
print_r($arr_xmp);
//打印结果:
Array (
[0] => DOMElement Object (
[tagName] => rdf:Description
[schemaTypeInfo] =>
[nodeName] => rdf:Description
[nodeValue] => Copyright FirstName lastname FirstName lastname Jurks on the move
New Jurks in Town Big City Jurks 8 8 8 107 Jurks Big City Free to use
[nodeType] => 1
[parentNode] => (object value omitted)
[childNodes] => (object value omitted)
[firstChild] => (object value omitted)
[lastChild] => (object value omitted)
[previousSibling] => (object value omitted)
[nextSibling] => (object value omitted)
[attributes] => (object value omitted)
[ownerDocument] => (object value omitted)
[namespaceURI] => http://www.w3.org/1999/02/22-rdf-syntax-ns# [prefix] => rdf
[localName] => Description
[baseURI] => xmp-cache-test.xml
[textContent] => Copyright FirstName lastname FirstName lastname Jurks on the move
New Jurks in Town Big City Jurks 8 8 8 107 Jurks Big City Free to use
) )
上述结果并非我的预期。 我宁愿在数组中查看更像下面的例子 以及其他一些选择:
Array (
[rdf:about] =>
[xmlns:photoshop] => http://ns.adobe.com/photoshop/1.0/
[xmlns:dc] => http://purl.org/dc/elements/1.1/
[xmlns:tiff] => http://ns.adobe.com/tiff/1.0/
[xmlns:exif] => http://ns.adobe.com/exif/1.0/
[xmlns:xmp] => http://ns.adobe.com/xap/1.0/
[xmlns:aux] => http://ns.adobe.com/exif/1.0/aux/
[xmlns:crs] => http://ns.adobe.com/camera-raw-settings/1.0/
[xmlns:Iptc4xmpCore] => http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/
[xmlns:xmpRights] => http://ns.adobe.com/xap/1.0/rights/
[photoshop:LegacyIPTCDigest] => B0D1E9B9CFC1C774E7277517B04970DC
[photoshop:ColorMode] => 3
[photoshop:ICCProfile] => sRGB IEC61966-2.1
[photoshop:AuthorsPosition] => Tester
[photoshop:Headline] => Big City Landscape
[photoshop:CaptionWriter] => Freelancer
[photoshop:DateCreated] => 2016-08-05T02:16Z
[photoshop:City] => NA
[photoshop:City] => NA
[photoshop:State] => NA
[photoshop:Country] => NA
[photoshop:TransmissionReference] => 2323
[photoshop:Instructions] => set to landscape
[photoshop:Credit] => Photographor: FirstName lastname
[photoshop:Source] => Smart Phone Photo
[tiff:Make] => Motorola
[tiff:Model] => MB865
[tiff:Orientation] => 1
------------ // continue
)
选项:举个例子会很有帮助。
答案 0 :(得分:0)
============= EDIT ===================
xml to array部分,这里的问题几乎相同:What is the best php DOM 2 Array function?
我玩了一些代码,这就是结果:
function xml_to_array($root) {
$result = array();
if ($root->hasAttributes()) {
$attrs = $root->attributes;
foreach ($attrs as $attr) {
$result['@attributes'][$attr->name] = $attr->value;
}
}
if ($root->hasChildNodes()) {
$children = $root->childNodes;
if ($children->length == 1) {
$child = $children->item(0);
if ($child->nodeType == XML_TEXT_NODE) {
$result['_value'] = $child->nodeValue;
return count($result) == 1
? $result['_value']
: $result;
}
}
$groups = array();
foreach ($children as $child) {
if($child->nodeType == XML_TEXT_NODE && empty(trim($child->nodeValue))) continue;
if (!isset($result[$child->nodeName])) {
$result[$child->nodeName] = xml_to_array($child);
} else {
if (!isset($groups[$child->nodeName])) {
$result[$child->nodeName] = array($result[$child->nodeName]);
$groups[$child->nodeName] = 1;
}
$result[$child->nodeName][] = xml_to_array($child);
}
}
}
return $result;
}
// $content = your xml raw source
if(preg_match("/(\<x\:xmpmeta.*?\>.*?\<\/x\:xmpmeta\>)/s", $content, $matches))
$data = "<?xml version='1.0'?>\n" . $matches[1];
$myXmlString = $data ;
//$myXmlFilename = $__data;
$doc = new DOMDocument();
$doc->loadXML($myXmlString);
$array = xml_to_array($doc);
print_r($array);
有人在那里写了非常简洁的函数,它遍历xml收集属性和节点值,并且几乎忽略了与可怕命名空间相关的痛苦。
如果您需要从数组中删除项目,只需使用unset,如:
unset($array['x:xmpmeta']['rdf:RDF']['rdf:Description']['tiff:BitsPerSample']);
至于如何更新属性值,请在此处完全相同的问题:Change tag attribute value with PHP DOMDocument
$dom = new DOMDocument();
$dom->loadHTML('<a href="http://foo.bar/">Click here</a>');
foreach ($dom->getElementsByTagName('a') as $item) {
$item->setAttribute('href', 'http://google.com/');
echo $dom->saveHTML();
exit;
}
最后,如何从数组反向转向DOM:没有简单的方法,您必须手动创建DOM对象并逐个创建节点和属性。
填充后,您可以调用http://php.net/manual/en/domdocument.savexml.php来获取xml代码。
<?php
$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;
$root = $doc->createElement('book');
$root = $doc->appendChild($root);
$title = $doc->createElement('title');
$title = $root->appendChild($title);
$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);
echo "Saving all the document:\n";
echo $doc->saveXML() . "\n";
echo "Saving only the title part:\n";
echo $doc->saveXML($title);
?>
希望这有帮助,