Home  >  Q&A  >  body text

Get the title after the first paragraph: XPath

<p>I want to add a FAQPage schema to my website. </p> <p>In order to do this, I need to find every <code><h2></code> or <code><h3></code> tag with a question mark. That's the problem. </p> <p>After that, I need the first <code><p></code> tag after the title as the answer. </p> <p>The final result should look like this:</p> <pre class="brush:php;toolbar:false;">{ "@type": "Question", "name": "How long does it take to process a refund?", "acceptedAnswer": { "@type": "Answer", "text": "Content obtained from the first P tag", "url": "https://www.example.com/answer#anchor_link" } }</pre> <ul> <li>The <code>"name"</code> in question is the <code><h2></code> or <code><h3></code> tag. </li> <li>The <code>"url"</code> of the answer is obtained from the <code><h2></code> or <code><h3></code> tag Permalinks and anchor links. </li> <li><strong>These two parameters have been resolved</strong></li> </ul> <p>Unfortunately, I can't find out how to get the first paragraph tag after the title tag.</p> <p>I need to get the content of the first paragraph in the following line: </p> <pre class="brush:php;toolbar:false;">"text": "Content obtained from the first P tag",</pre> <p>This is my current code: </p> <pre class="brush:php;toolbar:false;"><?php $content_postid = get_the_ID(); $content_post = get_post($content_postid); $content = $content_post->post_content; $content = apply_filters('the_content', $content); $content = str_replace(']]>', ']]>', $content); libxml_use_internal_errors(true); $dom = new DOMDocument; $dom->loadHTML('<?xml encoding="utf-8" ?>' . $content); $xp = new DOMXPath($dom); $query = "//h2[contains(., '?')] | //h3[contains(., '?')]"; $nodes = $xp->query($query); $stack = []; if ($nodes) { $faq_count = count($nodes); $faq_i = 1; echo ' <script type="application/ld json"> { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": ['; foreach($nodes as $node) { echo '{ "@type": "Question", "name": "'.$node->nodeValue.'", "acceptedAnswer": { "@type": "Answer", "text": "Content obtained from the first P tag", "url": "'.get_permalink().'#'.$node->getAttribute('id').'" } }'; if ($faq_i != $faq_count) : echo ','; endif; $faq_i ; } echo ']}</script>'; } ?></pre> <p>As you can see, I use this line of code to find every <code><h2></code> or <code> with <code>?</code> ;<h3></code>Tag:</p> <pre class="brush:php;toolbar:false;">$query = "//h2[contains(., '?')] | //h3[contains(., '?')]"; </pre> <p>I guess I need a second <code>$query</code> to find the paragraph after the title? But how to check the first tag after the title?</p> <p>I tried this additional query: </p> <pre class="brush:php;toolbar:false;">$query2 = "//h2[contains(., '?')]/following-sibling::p[1] | //h3[contains (., '?')]/following-sibling::p[1]";</pre> <p>But neither <code>following-sibling::</code> nor <code>following::</code> works. It always displays the paragraph after the last heading. </p> <p>Do I need to resolve the first query? to know what level am I at? </p> <p>Here is an example of <code>$content_post</code> (it is always different): </p> <pre class="brush:php;toolbar:false;"><h2>Lorem ipsum dolor sit amet?</h2> <p>consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim</p> <p>Veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p> <h3>Duis autem vel eum?</h3> <p>Iris dolor in hendrerit in vulputate velit Esse molestie consequential, vel illum dolore eu feugiat nulla facilisis at vero et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p> <h2>Nam liber tempor cum soluta?</h2> <h3>nobis eleifend option congue nihil</h3> <p>imperdiet doming id quod mazim placerat facer possim assum. <p>Et wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p> <h3>Duis autem vel?</h3> <p>Eum iriure dolor in hendrerit in vulputate velit essse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p> <h4>Nam liber tempor cum soluta nobis</h4> <p>eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.</p></pre> <p><br /></p>
P粉447002127P粉447002127398 days ago574

reply all(1)I'll reply

  • P粉957661544

    P粉9576615442023-08-21 18:20:03

    Try changing your foreach to the following and see if it works.

    foreach($nodes as $node) {
            $ans = $xp->query("./following-sibling::p[1]",$node)[0]->nodeValue;
            echo "{
                    '@type': 'Question',
                    'name': '".$node->nodeValue."',
                    'acceptedAnswer': {
                        '@type': 'Answer',
                        'text': {$ans}
                    }
                }";

    reply
    0
  • Cancelreply