如何在WordPress中使用XPath变量动态填充Schema?
WordPress自定义文章类型:XPath变量与MovingCompany Schema集成方案
问题背景
已为WordPress的company自定义文章类型配置了MovingCompany类型的Schema模板,同时有一组XPath规则用于提取页面中的企业信息,但不知道如何将XPath提取的内容自动填充到Schema的变量占位符中。
现有资源
XPath变量规则
xpath:movingcompany.name:body/main[1]/div[1]/div[1]/h1[1] xpath:movingcompany.address:body/main[1]/div[2]/div[1]/div[1]/div[1]/p[2]/span[1] xpath:movingcompany.image:body/main[1]/div[2]/div[1]/div[1]/div[2]/img[1] xpath:movingcompany.aggregateRating.ratingValue:body/main[1]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1] xpath:movingcompany.aggregateRating.ratingCount:body/main[1]/div[1]/div[1]/div[1]/div[1]/span[1]/span[2] xpath:movingcompany.aggregateRating.reviewCount:body/main[1]/div[1]/div[1]/div[1]/div[1]/span[1]/span[2] xpath:movingcompany.openingHoursSpecification.opens:body/main[1]/div[9]/div[1]/div[1]/div[1]/table[1]/tbody[1]/tr[1]/td[2]/div[1]/span[1] xpath:movingcompany.openingHoursSpecification.closes:body/main[1]/div[9]/div[1]/div[1]/div[1]/table[1]/tbody[1]/tr[1]/td[2]/div[1]/span[1]
Schema模板
{ "@context": "https://schema.org/", "@type": "MovingCompany", "name": "{{movingcompany.name}}", "address": "{{movingcompany.address}}", "image": "{{movingcompany.image}}", "aggregateRating": { "@type": "AggregateRating", "ratingValue": "{{movingcompany.aggregateRating.ratingValue}}", "ratingCount": "{{movingcompany.aggregateRating.ratingCount}}", "reviewCount": "{{movingcompany.aggregateRating.reviewCount}}" }, "openingHoursSpecification": { "@type": "OpeningHoursSpecification", "opens": "{{movingcompany.openingHoursSpecification.opens}}", "closes": "{{movingcompany.openingHoursSpecification.closes}}", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ] } }
集成解决方案
以下是在WordPress中实现XPath提取+Schema填充的具体步骤,代码可直接添加到主题的functions.php文件中:
1. 编写XPath内容提取函数
该函数负责接收文章ID和XPath表达式,解析文章内容并返回对应的值(处理文本和图片属性两种情况):
function get_xpath_content($post_id, $xpath_expr) { // 获取文章内容 $post_content = get_post_field('post_content', $post_id); if (empty($post_content)) return ''; // 初始化DOM解析器 libxml_use_internal_errors(true); // 忽略HTML解析警告 $dom = new DOMDocument(); $dom->loadHTML('<html><body>' . $post_content . '</body></html>'); $xpath = new DOMXPath($dom); // 执行XPath查询 $nodes = $xpath->query($xpath_expr); if ($nodes->length === 0) return ''; $node = $nodes->item(0); // 判断是否是图片节点,提取src属性 if ($node->nodeName === 'img') { return $node->getAttribute('src'); } // 其他节点返回文本内容 return trim($node->nodeValue); }
2. 映射XPath与Schema字段
将XPath规则整理为关联数组,键对应Schema中的占位符名称,值为XPath表达式:
function get_schema_xpath_mapping() { return [ 'movingcompany.name' => 'body/main[1]/div[1]/div[1]/h1[1]', 'movingcompany.address' => 'body/main[1]/div[2]/div[1]/div[1]/div[1]/p[2]/span[1]', 'movingcompany.image' => 'body/main[1]/div[2]/div[1]/div[1]/div[2]/img[1]', 'movingcompany.aggregateRating.ratingValue' => 'body/main[1]/div[1]/div[1]/div[1]/div[1]/span[1]/span[1]', 'movingcompany.aggregateRating.ratingCount' => 'body/main[1]/div[1]/div[1]/div[1]/div[1]/span[1]/span[2]', 'movingcompany.aggregateRating.reviewCount' => 'body/main[1]/div[1]/div[1]/div[1]/div[1]/span[1]/span[2]', 'movingcompany.openingHoursSpecification.opens' => 'body/main[1]/div[9]/div[1]/div[1]/div[1]/table[1]/tbody[1]/tr[1]/td[2]/div[1]/span[1]', 'movingcompany.openingHoursSpecification.closes' => 'body/main[1]/div[9]/div[1]/div[1]/div[1]/table[1]/tbody[1]/tr[1]/td[2]/div[1]/span[1]' ]; }
3. 生成并输出Schema JSON-LD
通过钩子在页面头部输出填充好的Schema,仅在company自定义文章类型的单页生效:
function output_moving_company_schema() { // 仅在company自定义文章类型单页执行 if (!is_singular('company')) return; $post_id = get_the_ID(); $mapping = get_schema_xpath_mapping(); $schema_template = '{ "@context": "https://schema.org/", "@type": "MovingCompany", "name": "{{movingcompany.name}}", "address": "{{movingcompany.address}}", "image": "{{movingcompany.image}}", "aggregateRating": { "@type": "AggregateRating", "ratingValue": "{{movingcompany.aggregateRating.ratingValue}}", "ratingCount": "{{movingcompany.aggregateRating.ratingCount}}", "reviewCount": "{{movingcompany.aggregateRating.reviewCount}}" }, "openingHoursSpecification": { "@type": "OpeningHoursSpecification", "opens": "{{movingcompany.openingHoursSpecification.opens}}", "closes": "{{movingcompany.openingHoursSpecification.closes}}", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ] } }'; // 替换所有占位符 foreach ($mapping as $placeholder_key => $xpath_expr) { $content = get_xpath_content($post_id, $xpath_expr); $schema_template = str_replace("{{$placeholder_key}}", $content, $schema_template); } // 输出JSON-LD echo '<script type="application/ld+json">' . $schema_template . '</script>'; } add_action('wp_head', 'output_moving_company_schema');
注意事项
- 你的XPath中
ratingCount和reviewCount指向同一个节点,opens和closes也指向同一个节点,若实际页面中这些值不同,需要调整XPath表达式。 - 如果文章内容的HTML结构发生变化,需要同步更新XPath规则,否则会提取失败。
- 可以添加错误处理逻辑,比如当某个字段提取为空时,移除对应的Schema属性,避免出现空值。
内容的提问来源于stack exchange,提问作者Nuriddin Gulamov
相关产品推荐
相关产品推荐

