php - 如何插入 g: 在 XML 节点之前
问题描述
我找到了这个线程: 如何使用 SimpleXmlElement 编写 CDATA?
所以我按照它创建了一个 XML 提要。
例如,它返回给我这个:
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title>
<![CDATA[ Site title ]]>
</title>
<link>https://www.example.com</link>
<description>
<![CDATA[ Site description ]]>
</description>
<item>
<id>ABCD</id>
<title>
<![CDATA[ Productname ]]>
</title>
<description>
<![CDATA[ Product description ]]>
</description>
<gtin>
<![CDATA[ ]]>
</gtin>
<mpn>
<![CDATA[ 3305 ]]>
</mpn>
</item>
</channel>
</rss>
<gtin>
例如,我怎样才能做到<mpn>
:
<g:gtin>
和<g:mpn>
这是我的php
代码:
<?php
class SimpleXMLExtended extends SimpleXMLElement {
public function addCData($cdata_text) {
$node = dom_import_simplexml($this);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($cdata_text));
}
}
$xmlFile = 'feed_nl.xml';
$xml = new SimpleXMLExtended('<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"/>');
$channel = $xml->addChild('channel');
$channel->title = NULL;
$channel->title->addCData('Site title');
$channel->addChild('link', "https://www.example.com/");
$channel->description = NULL;
$channel->description->addCData('Site description');
$query = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'suppress_filters' => false
) );
while ( $query->have_posts() ) : $query->the_post();
$post_id = get_the_ID();
$product = wc_get_product( $post_id );
$product_title = get_the_title();
$product_description = get_the_excerpt();
$mpn = $product->get_sku();
$gtin = get_field('barcode');
$item->title = NULL;
$item->title->addCData($product_title);
$item->description = NULL;
$item->description->addCData($product_description);
$item->gtin = NULL;
$item->gtin->addCData($gtin);
$item->mpn = NULL;
$item->mpn->addCData($mpn);
endwhile;
$xml->saveXML($xmlFile);
?>
最终代码:
<?php
class SimpleXMLElementExtended extends SimpleXMLElement{
public function addChildWithCDATA($name , $value, $google) {
if ($google) {
$new = parent::addChild($name, '', $google);
} else {
$new = parent::addChild($name);
}
$base = dom_import_simplexml($new);
$docOwner = $base->ownerDocument;
$base->appendChild($docOwner->createCDATASection($value));
}
}
$GOOGLE_BASE_NS = 'http://base.google.com/ns/1.0';
$xmlFile = 'feed_test.xml';
// instead of $xml = new SimpleXMLElement('<site/>');
$xml = new SimpleXMLElementExtended(
'<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"/>'
);
$channel = $xml->addChild('channel');
$channel->addChildWithCDATA('title', 'Site title', '');
$channel->addChild('link', "https://www.example.com");
$query = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 1,
'suppress_filters' => false
) );
while ( $query->have_posts() ) : $query->the_post();
$post_id = get_the_ID();
$product = wc_get_product( $post_id );
$product_title = get_the_title();
$product_description = get_the_excerpt();
$product_link = get_the_permalink();
$product_link = $product_link . "?source=googlebase";
$product_thumbnail_url = get_the_post_thumbnail_url();
$attachment_ids = $product->get_gallery_image_ids();
$availability = $product->get_availability();
$availability = $availability['class'];
$availability = str_replace('-', ' ', $availability);
$price = $product->get_price();
if (empty($price)) {$price = '0.00';}
$price = $price . " EUR";
$mpn = $product->get_sku();
$gtin = get_field('barcode');
$item = $channel->addChild('item', '', '');
$item->addChild('id', $post_id, $GOOGLE_BASE_NS);
$item->addChild('link', $product_link);
$item->addChild('image_link', $product_thumbnail_url, $GOOGLE_BASE_NS);
foreach( $attachment_ids as $attachment_id ) {
$image_link = wp_get_attachment_url( $attachment_id );
$item->addChild('additional_image_link', $image_link, $GOOGLE_BASE_NS);
}
$item->addChild('availability', $availability, $GOOGLE_BASE_NS);
$item->addChild('price', $price, $GOOGLE_BASE_NS);
$item->addChild('condition', "new", $GOOGLE_BASE_NS);
$item->addChildWithCDATA('gtin', $gtin, $GOOGLE_BASE_NS);
endwhile;
$xml->saveXML($xmlFile);
?>
解决方案
XML 中以冒号分隔的前缀是名称空间的别名。检查祖先节点是否最近xmlns:*
。这是别名的定义。
XML 解析器会将以下所有示例读取为{http://base.google.com/ns/1.0}gtin
.
<gtin xmlns="http://base.google.com/ns/1.0}gtin"/>
<g:gtin xmlns:g="http://base.google.com/ns/1.0}gtin"/>
<google:gtin xmlns:google="http://base.google.com/ns/1.0}gtin"/>
要创建具有命名空间的元素节点,您必须提供命名空间。因为SimpleXMLElement::addChild()
这是第三个论点。前缀是节点名称的一部分——第一个参数。
// define a constant for the namespace uri literal
const GOOGLE_BASE_NS = 'http://base.google.com/ns/1.0';
$rss = new SimpleXMLElement(
'<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"/>'
);
// implicit namespace handling - can inherit
$channel = $rss->addChild('channel');
// explicit no namespace
$item = $channel->addChild('item', '', '');
// explicit namespace with prefix
$item->addChild('g:gtin', 'example', GOOGLE_BASE_NS);
echo $rss->asXML();
推荐阅读
- typescript - React-Native-Reanimated 和 React-native
- r - 根据两个数据框中的列有条件地替换值
- java - 如何在eclipse中自动搜索maven依赖?
- c++ - 在不破坏现有代码的情况下添加新枚举
- python - 使用 python - tkinter 设置根窗口的单一维度的方法?
- json - Ansible 漂亮的打印 json
- .net - 在云端混淆应用程序设置文件,但允许本地应用程序开发
- c - TCL:在嵌入 C 时调用 TCL 包
- javascript - 如何根据设备使 JavaScript 打开页面?
- javascript - 我在 useState 中发现错误了吗?还是我不明白它是如何工作的?