XPath에 대한 형제 인 XSLT을 고려해보십시오. 본질적으로 XML을 변형하고 있으므로 실제로는 선택 값을 파싱하지 않습니다. XSLT를 사용하면 foreach
루프가 필요하지 않으며 네임 스페이스를 적절히 처리 할 수 있습니다.
간단한 XML(@IMSoP에서)
: XSLT 아래와 같이 사실
은 (SimpleXML
쿼리 및 평가 XPath
)를 <feed ...>
루트에 싸여 게시 된 XML을 사용하여 상기 방법 중 가장 빠른
$time_start = microtime(true);
$xml = file_get_contents('YoutubeFeed.xml');
$document = new SimpleXMLElement($xml);
define('NS_ATOM', 'http://www.w3.org/2005/Atom');
define('NS_MEDIA', 'http://search.yahoo.com/mrss/');
foreach ($document->children(NS_ATOM)->entry as $entry) {
echo "<item>".PHP_EOL;
echo "<title>".$entry->title."</title>".PHP_EOL;
echo "<link>".$entry->link->attributes(null)->href."</link>".PHP_EOL;
echo "<image>".$entry->children(NS_MEDIA)->thumbnail->attributes()->url."</image>".PHP_EOL;
echo "<description>".$entry->children(NS_MEDIA)->description."</description>".PHP_EOL;
echo "<guid>".$entry->children(NS_MEDIA)->guid."</guid>".PHP_EOL;
echo "<views>".$entry->children(NS_MEDIA)->statistics->attributes()->views."</views>".PHP_EOL;
echo "<pubDate>".$entry->published."</pubDate>".PHP_EOL;
echo "</item>".PHP_EOL;
}
타이밍
echo "SimpleXML: " . (microtime(true) - $time_start) ."\n";
# SimpleXML: 0.0014688968658447
,
XPATH(@ThW부터)
$time_start = microtime(true);
$xml = file_get_contents('YoutubeFeed.xml');
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('media', 'http://search.yahoo.com/mrss/');
foreach ($xpath->evaluate('//atom:entry') as $entry) {
echo "<item>".PHP_EOL;
echo "<title>". $xpath->evaluate('string(atom:title)', $entry)."</title>".PHP_EOL;
echo "<link>". $xpath->evaluate('string(atom:link/@href)', $entry)."</link>".PHP_EOL;
echo "<image>". $xpath->evaluate('string(media:thumbnail/@url)', $entry)."</image>".PHP_EOL;
echo "<description>". $xpath->evaluate('string(media:description)', $entry)."</description>".PHP_EOL;
echo "<guid>". $xpath->evaluate('string(media:guid)', $entry)."</description>".PHP_EOL;
echo "<views>".$xpath->evaluate('string(media:statistics/@views)', $entry)."</guid>".PHP_EOL;
echo "<pubDate>". $xpath->evaluate('string(atom:pubdate)', $entry)."</views>".PHP_EOL;
echo "</item>".PHP_EOL;
}
타이밍
echo "XPATH: " . (microtime(true) - $time_start) ."\n";
# XPATH: 0.0012829303741455
XSLT
$time_start = microtime(true);
$xml = file_get_contents('YoutubeFeed.xml');
$document = new DOMDocument();
$document->loadXml($xml);
$xslstr = '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"
exclude-result-prefixes="atom media">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="feed">
<xsl:apply-templates select="atom:entry"/>
</xsl:template>
<xsl:template match="atom:entry">
<item>
<title><xsl:value-of select="atom:title"/></title>
<link><xsl:value-of select="atom:link/@href"/></link>
<image><xsl:value-of select="atom:thumbnail/@url"/></image>
<description><xsl:value-of select="media:description"/></description>
<guid><xsl:value-of select="media:guid"/></guid>
<views><xsl:value-of select="media:statistics/@views"/></views>
<pubDate><xsl:value-of select="atom:pubdate"/></pubDate>
</item>
</xsl:template>
</xsl:stylesheet>';
$xsl = new DOMDocument;
$xsl->loadXML($xslstr);
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXML = $proc->transformToXML($document);
// Echo string output
echo $newXML;
타이밍
더욱
<entry>
노드, 복사 태그 500 선에 아이들과 함께 3,691,363,210
echo "XSLT: " . (microtime(true) - $time_start) ."\n";
# XSLT: 0.00098896026611328
는, XSLT는 훨씬 더 확장 할 수 있습니다. 아래의 단위는 초입니다.
# SimpleXML: 0.62154388427734
# XPATH: 0.68382000923157
# XSLT: 0.011976957321167
귀하의 XML 형식이 올바르지 않습니다 (즉, 유효하지 않습니다). [XML 1.0의 W3C 네임 스페이스] (https://www.w3.org/TR/REC-xml-names/#ns-using)에 따르면 : xml이나 xmlns가 아닌 네임 스페이스 접두어는 반드시 네임 스페이스 선언 특성 *에서 선언되었습니다. 그러므로'media' 접두사를 선언해야합니다. – Parfait
DOM + Xpath를 사용하면 훨씬 어려워집니다. DOMXpath 인스턴스에 자신의 접두사를 등록하고 DOMXpath :: evaluate()을 사용하여 노드 목록과 값을 가져옵니다. – ThW
지금 당장 풀 답변을 쓸 시간이 없지만 찾고있는 방법은 ['-> children()'] (http://php.net/manual/en/simplexmlelement.children. PHP). 접두사가 아닌 실제 네임 스페이스 URI ('xmlns : media' 속성에서)를 하드 코딩하는 것이 좋겠지 만'$ val-> children ('media', true) -> description ' 소스 문서가 다른 접두사로 다시 생성되는 경우 – IMSoP