【问题标题】:Parsing XML with PHP for Wordpress Product List使用 PHP 为 Wordpress 产品列表解析 XML
【发布时间】:2014-10-29 16:09:32
【问题描述】:

我正在尝试用 PHP 解析一个 XML 文件,以便我可以替换某个标签的值。

这是相关 XML 的样子:

<channel>
    <item>
        <title>Woo Logo</title>
        <link>http://demo2.woothemes.com/woocommerce/product/woo-logo/</link>
        <pubDate>Fri, 07 Jun 2013 10:35:51 +0000</pubDate>
        <dc:creator>wooteam</dc:creator>
        <guid isPermaLink="false">http://demo2.woothemes.com/dummydata/?post_type=product&#038;p=15</guid>
        <description></description>
        <content:encoded><![CDATA[Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.]]></content:encoded>
        <excerpt:encoded><![CDATA[Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.]]></excerpt:encoded>
        <wp:post_id>15</wp:post_id>
        <wp:post_date>2013-06-07 10:35:51</wp:post_date>
        <wp:post_date_gmt>2013-06-07 10:35:51</wp:post_date_gmt>
        <wp:comment_status>open</wp:comment_status>
        <wp:ping_status>closed</wp:ping_status>
        <wp:post_name>woo-logo</wp:post_name>
        <wp:status>publish</wp:status>
        <wp:post_parent>0</wp:post_parent>
        <wp:menu_order>0</wp:menu_order>
        <wp:post_type>product</wp:post_type>
        <wp:post_password></wp:post_password>
        <wp:is_sticky>0</wp:is_sticky>
        <category domain="product_cat" nicename="clothing"><![CDATA[Clothing]]></category>
        <category domain="product_type" nicename="simple"><![CDATA[simple]]></category>
        <category domain="product_cat" nicename="t-shirts"><![CDATA[T-shirts]]></category>
        <wp:postmeta>
            <wp:meta_key>_edit_last</wp:meta_key>
            <wp:meta_value><![CDATA[3]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_thumbnail_id</wp:meta_key>
            <wp:meta_value><![CDATA[16]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_visibility</wp:meta_key>
            <wp:meta_value><![CDATA[visible]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_stock_status</wp:meta_key>
            <wp:meta_value><![CDATA[instock]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>total_sales</wp:meta_key>
            <wp:meta_value><![CDATA[0]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_downloadable</wp:meta_key>
            <wp:meta_value><![CDATA[no]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_virtual</wp:meta_key>
            <wp:meta_value><![CDATA[no]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_product_image_gallery</wp:meta_key>
            <wp:meta_value><![CDATA[17]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_regular_price</wp:meta_key>
            <wp:meta_value><![CDATA[20]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_sale_price</wp:meta_key>
            <wp:meta_value><![CDATA[18]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_tax_status</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_tax_class</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_purchase_note</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_featured</wp:meta_key>
            <wp:meta_value><![CDATA[no]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_weight</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_length</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_width</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_height</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_sku</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_product_attributes</wp:meta_key>
            <wp:meta_value><![CDATA[a:0:{}]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_sale_price_dates_from</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_sale_price_dates_to</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_price</wp:meta_key>
            <wp:meta_value><![CDATA[18]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_sold_individually</wp:meta_key>
            <wp:meta_value><![CDATA[]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_stock</wp:meta_key>
            <wp:meta_value><![CDATA[5]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_backorders</wp:meta_key>
            <wp:meta_value><![CDATA[no]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_manage_stock</wp:meta_key>
            <wp:meta_value><![CDATA[yes]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_upsell_ids</wp:meta_key>
            <wp:meta_value><![CDATA[a:1:{i:0;s:2:"60";}]]></wp:meta_value>
        </wp:postmeta>
        <wp:comment>
            <wp:comment_id>13</wp:comment_id>
            <wp:comment_author><![CDATA[Cobus Bester]]></wp:comment_author>
            <wp:comment_author_email>bester.c@gmail.com</wp:comment_author_email>
            <wp:comment_author_url></wp:comment_author_url>
            <wp:comment_author_IP>196.215.9.147</wp:comment_author_IP>
            <wp:comment_date>2013-06-07 11:57:05</wp:comment_date>
            <wp:comment_date_gmt>2013-06-07 11:57:05</wp:comment_date_gmt>
            <wp:comment_content><![CDATA[Simple and effective design. One of my favorites.]]></wp:comment_content>
            <wp:comment_approved>1</wp:comment_approved>
            <wp:comment_type></wp:comment_type>
            <wp:comment_parent>0</wp:comment_parent>
            <wp:comment_user_id>0</wp:comment_user_id>
            <wp:commentmeta>
                <wp:meta_key>akismet_error</wp:meta_key>
                <wp:meta_value><![CDATA[1370606225]]></wp:meta_value>
            </wp:commentmeta>
            <wp:commentmeta>
                <wp:meta_key>akismet_history</wp:meta_key>
                <wp:meta_value><![CDATA[a:4:{s:4:"time";d:1370606225.6765859127044677734375;s:7:"message";s:92:"Akismet was unable to check this comment (response: ), will automatically retry again later.";s:5:"event";s:11:"check-error";s:4:"user";s:0:"";}]]></wp:meta_value>
            </wp:commentmeta>
            <wp:commentmeta>
                <wp:meta_key>akismet_as_submitted</wp:meta_key>
                <wp:meta_value><![CDATA[a:67:{s:15:"comment_post_ID";i:15;s:14:"comment_author";s:12:"Cobus Bester";s:20:"comment_author_email";s:18:"bester.c@gmail.com";s:18:"comment_author_url";N;s:15:"comment_content";s:49:"Simple and effective design. One of my favorites.";s:12:"comment_type";s:0:"";s:14:"comment_parent";i:0;s:7:"user_ID";i:0;s:7:"user_ip";s:13:"196.215.9.147";s:10:"user_agent";s:119:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31";s:8:"referrer";s:56:"http://demo2.woothemes.com/woocommerce/product/woo-logo/";s:4:"blog";s:38:"http://demo2.woothemes.com/woocommerce";s:9:"blog_lang";s:5:"en_US";s:12:"blog_charset";s:5:"UTF-8";s:9:"permalink";s:56:"http://demo2.woothemes.com/woocommerce/product/woo-logo/";s:21:"akismet_comment_nonce";s:6:"passed";s:11:"POST_author";s:12:"Cobus Bester";s:10:"POST_email";s:18:"bester.c@gmail.com";s:11:"POST_rating";s:1:"4";s:12:"POST_comment";s:49:"Simple and effective design. One of my favorites.";s:7:"POST__n";s:10:"a80bd2f042";s:21:"POST__wp_http_referer";s:30:"/woocommerce/product/woo-logo/";s:11:"POST_submit";s:13:"Submit Review";s:20:"POST_comment_post_ID";s:2:"15";s:19:"POST_comment_parent";s:1:"0";s:26:"POST_akismet_comment_nonce";s:10:"bbd941e9bf";s:15:"SERVER_SOFTWARE";s:6:"Apache";s:11:"REQUEST_URI";s:33:"/woocommerce/wp-comments-post.php";s:15:"REDIRECT_IS_WPE";s:1:"1";s:27:"REDIRECT_WPE_CAN_WRITE_DISK";s:1:"0";s:15:"REDIRECT_STATUS";s:3:"200";s:6:"IS_WPE";s:1:"1";s:18:"WPE_CAN_WRITE_DISK";s:1:"0";s:9:"HTTP_HOST";s:19:"demo2.woothemes.com";s:13:"HTTP_X_LB_KEY";s:8:"woodemo2";s:13:"HTTP_X_IS_BOT";s:1:"0";s:15:"HTTP_USER_AGENT";s:119:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31";s:15:"HTTP_CONNECTION";s:5:"close";s:14:"CONTENT_LENGTH";s:3:"273";s:18:"HTTP_CACHE_CONTROL";s:9:"max-age=0";s:11:"HTTP_ACCEPT";s:63:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";s:11:"HTTP_ORIGIN";s:26:"http://demo2.woothemes.com";s:12:"CONTENT_TYPE";s:33:"application/x-www-form-urlencoded";s:12:"HTTP_REFERER";s:56:"http://demo2.woothemes.com/woocommerce/product/woo-logo/";s:20:"HTTP_ACCEPT_ENCODING";s:17:"gzip,deflate,sdch";s:20:"HTTP_ACCEPT_LANGUAGE";s:14:"en-US,en;q=0.8";s:19:"HTTP_ACCEPT_CHARSET";s:30:"ISO-8859-1,utf-8;q=0.7,*;q=0.3";s:11:"HTTP_COOKIE";s:0:"";s:4:"PATH";s:28:"/usr/local/bin:/usr/bin:/bin";s:16:"SERVER_SIGNATURE";s:0:"";s:11:"SERVER_NAME";s:19:"demo2.woothemes.com";s:11:"SERVER_ADDR";s:9:"127.0.0.1";s:11:"SERVER_PORT";s:2:"80";s:11:"REMOTE_ADDR";s:13:"196.215.9.147";s:13:"DOCUMENT_ROOT";s:26:"/nas/wp/www/sites/woodemo2";s:12:"SERVER_ADMIN";s:18:"[no address given]";s:15:"SCRIPT_FILENAME";s:47:"/nas/wp/www/sites/woodemo2/wp-comments-post.php";s:11:"REMOTE_PORT";s:5:"57596";s:12:"REDIRECT_URL";s:33:"/woocommerce/wp-comments-post.php";s:17:"GATEWAY_INTERFACE";s:7:"CGI/1.1";s:15:"SERVER_PROTOCOL";s:8:"HTTP/1.0";s:14:"REQUEST_METHOD";s:4:"POST";s:12:"QUERY_STRING";s:0:"";s:11:"SCRIPT_NAME";s:21:"/wp-comments-post.php";s:8:"PHP_SELF";s:21:"/wp-comments-post.php";s:12:"REQUEST_TIME";s:10:"1370606225";s:25:"comment_post_modified_gmt";s:19:"2013-06-07 11:15:25";}]]></wp:meta_value>
            </wp:commentmeta>
            <wp:commentmeta>
                <wp:meta_key>rating</wp:meta_key>
                <wp:meta_value><![CDATA[4]]></wp:meta_value>
            </wp:commentmeta>
            <wp:commentmeta>
                <wp:meta_key>akismet_history</wp:meta_key>
                <wp:meta_value><![CDATA[a:4:{s:4:"time";d:1370607940.89634990692138671875;s:7:"message";s:46:"wooteam changed the comment status to approved";s:5:"event";s:15:"status-approved";s:4:"user";s:7:"wooteam";}]]></wp:meta_value>
            </wp:commentmeta>
        </wp:comment>
    </item>
</channel>

我对与价格有关的 wp:postmeta 块感兴趣 - 与 &lt;wp:meta_key&gt;_price&lt;/wp:meta_key&gt; 的块。这是我尝试做的:

$dom=new DOMDocument();
$dom->load("/var/www/wp-content/plugins/woocommerce/dummy-data/nspro.xml");

$root=$dom->documentElement;

$markers=$root->getElementsByTagName('item');

echo $markers->item(0)->getElementsByTagName('wp:postmeta')->item(22)->getElementsByTagName('wp:meta_key')->item(0)->textContent;

这不起作用 - 我收到此错误:

Fatal error: Call to a member function getElementsByTagName() on a non-object.

错误是在$markers-&gt;item(0)-&gt;getElementsByTagName('wp:postmeta')-&gt;item(22)-&gt; 之后使用该函数引用我的调用。显然,当我引用列表中的第一个 &lt;item&gt; 时,我不能像使用它一样使用它。如何访问 &lt;wp:postmeta&gt; 块内的标签?

【问题讨论】:

  • 为什么不改为simplexml
  • @Mr.Smith 这只是我发现的一种方法——如果你可以提供一个 simplexml 示例并且它可以工作,我很乐意使用它。
  • 刚刚看到了这个链接:这看起来很棒,我试试吧 城市->街道->地址->房屋颜色; ?>
  • 是的,这就是为什么它被称为 Simple XML :)
  • @Mr.Smith - 我正在尝试使用 simplexml - 你能告诉我我做错了什么 - 你可能会得到我想要做的事情...echo $xml-&gt;channel-&gt;item[$startval + $counter]-&gt;wp:postmeta[22]-&gt;wp:meta_key; 我正在尝试获得要编辑的正确项目-这就是我在循环中使用计数器的原因-但是我遇到了内部服务器错误,所以很明显我的语法是关闭的...看起来肯定是错误的-但我不确定什么是正确的: )

标签: php xml parsing object


【解决方案1】:

您没有在示例 XML 中发布相关内容。文档元素包含命名空间定义(xmlns:* 属性)。您要查找的数据位于 xmlns:wp 属性定义的命名空间中。

您可以使用 Xpath 以更简单、更稳定的方式获取数据。

$dom = new DOMDocument();
$dom->loadXML($xml);
// create an XPath instance
$xpath = new DOMXpath($dom);
// register a prefix for the wordpress export namespace
$xpath->registerNamespace('wp', 'http://wordpress.org/export/1.0/');

// fetch all rss item element nodes and iterate them
foreach ($xpath->evaluate('//item') as $item) {
  // get the price meta data as a number
  var_dump(
    $xpath->evaluate(
      'number(.//wp:postmeta[wp:meta_key = "_price"]/wp:meta_value)',
      $item
    )
  );
}

演示:https://eval.in/188516

输出:

float(18)

现在,如果您想编辑某些内容,您需要将其作为节点获取。如果 Xpath 表达式是一个位置路径,它总是会返回一个节点列表,很像 getElementsByTagName()。您可以检查列表是否包含值,但我更喜欢在 Xpath 中进行限制,只使用 foreach()。

// inside the item loop
$priceNodes = $xpath->evaluate(
  './/wp:postmeta[wp:meta_key = "_price"][1]/wp:meta_value', $item
);
foreach ($priceNodes as $priceNode) {
  $newPrice = 42; 
  $priceNode->nodeValue = (int)$newPrice;
}

演示:https://eval.in/188529

小心使用 DOMNode::$nodeValue。仅设置不能包含&amp; 的值。 PHP 在这里有一个错误。否则使用它来删除所有子节点并附加一个新的文本节点。

$priceNode->nodeValue = '';
$priceNode->appendChild($dom->createTextNode($newPrice));

【讨论】:

  • 这很好用!我现在要去谷歌搜索,但也许你可以帮我省点麻烦,告诉我如何用 xpath 替换 wp:meta_value
  • 不完全是 Xpath。 DOMXpath 是 ext/dom 的一部分。您只需使用 dom 函数。我在答案中添加了一个示例。
【解决方案2】:

所以这应该有效:

$xml = file_get_contents('/var/www/wp-content/plugins/woocommerce/dummy-data/nspro.xml');
$content = simplexml_load_string($xml);

echo $content->item->postmeta[22]->meta_key;

我的代码输出是:

_price

【讨论】:

  • 我按照你说的试了一下,我得到了:Notice: Trying to get property of non-object
  • 但我有一个变量$startval,它是我要编辑的项目的索引 - 因为在我的 xml 文件中有多个项目 - 我怎么会喜欢 - 第 55 个 @ 987654325@?
  • 我在想$content-&gt;item[$startval]-&gt;postmeta[22]-&gt;meta_key;,但这似乎行不通。
  • 我不知道你的 XML 是什么样子的。您的描述看起来与您在问题中发布的内容不同...
  • 是的,它略有不同-只有一个以上的项目-我无法在问题中全部发布-基本上在$content之后应该有一个数组(或类似的结构) 的item's
猜你喜欢
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 2012-12-22
  • 1970-01-01
  • 2010-11-10
  • 2017-05-06
  • 2015-04-13
相关资源
最近更新 更多