Как извлечь HTML-разметку внутри узла XML с XPath - PullRequest
0 голосов
/ 04 октября 2019

Я использую DOMDocument и XPath .

Данные для следующего XML

<Description>
    <CompleteText>
        <DetailTxt>
            <Text>
                <span>Here there is some text</span>
                <h2>And maybe a headline</h2>
                <br/>
                <span>Normal position</span>
                <br/>
                <span> </span>
                <br/>
            </Text>
        </DetailTxt>            
    </CompleteText>
</Description>

Узел /Description/CompleteText/DetailTxt/Text содержит разметку,к сожалению, не ушел, но я не могу это изменить. Есть ли вероятность, что я смогу запросить этот контент с поддержкой разметки html?

Что я пробовал

Очевидно, nodeValue , но также textContent. Оба дают мне содержание без разметки.

Ответы [ 2 ]

1 голос
/ 06 октября 2019

Вы можете использовать saveHTML метод DOMDocument для сериализации узла как HTML, в вашем случае вы, кажется, хотите вызвать его на каждом дочернем узле выбранного узла и объединить строки;в API-интерфейсе DOM браузера, который будет называться innerHTML, поэтому я написал для этого функцию с таким именем, а также использовал возможность вызова функций PHP из XPath в следующем фрагменте:

<?php
$xml = <<<'EOD'
<Description>
    <CompleteText>
        <DetailTxt>
            <Text>
                <span>Here there is some text</span>
                <h2>And maybe a headline</h2>
                <br/>
                <span>Normal position</span>
                <br/>
                <span> </span>
                <br/>
            </Text>
        </DetailTxt>            
    </CompleteText>
</Description>  
EOD;

$doc = new DOMDocument();

$doc->loadXML($xml);

$xpath = new DOMXPath($doc);

function innerHTML($nodeList) {
  $node = $nodeList[0];
  $html = '';
  $containingDoc = $node->ownerDocument;
  foreach ($node->childNodes as $child) {
      $html .= $containingDoc->saveHTML($child);
    }
  return $html;
}

$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPHPFunctions("innerHTML");



$innerHTML = $xpath->evaluate('php:function("innerHTML", /Description/CompleteText/DetailTxt/Text)');

echo $innerHTML;

Вывести какhttp://sandbox.onlinephpfunctions.com/code/62a980e2d2a2485c2648e16fc647a6bd6ff5620b -

            <span>Here there is some text</span>
            <h2>And maybe a headline</h2>
            <br>
            <span>Normal position</span>
            <br>
            <span> </span>
            <br>
0 голосов
/ 08 октября 2019

Я нахожу хороший результат при использовании метода C14n DOMNode .

http://sandbox.onlinephpfunctions.com/code/90dc915c9a43c91d31fcd47d37e89df430951b2e

<?php
$xml = <<<'EOD'
<Description>
    <CompleteText>
        <DetailTxt>
            <Text>
                <span>Here there is some text</span>
                <h2>And maybe a headline</h2>
                <br/>
                <span>Normal position</span>
                <br/>
                <span> </span>
                <br/>
            </Text>
        </DetailTxt>            
    </CompleteText>
</Description>  
EOD;

$doc = new DOMDocument();

$doc->loadXML($xml);

$xpath = new DOMXPath($doc);

function innerHTML($nodeList) {
  $node = $nodeList[0];
  $html = '';
  $containingDoc = $node->ownerDocument;
  foreach ($node->childNodes as $child) {
      $html .= $containingDoc->saveHTML($child);
    }
  return $html;
}

$xpath->registerNamespace("php", "http://php.net/xpath");


$domNodes = $xpath->query('/Description/CompleteText/DetailTxt/Text');
$domNode = $domNodes[0];
$innerHTML = $domNode->C14N();

echo $innerHTML;

Результат

<Text>
                <span>Here there is some text</span>
                <h2>And maybe a headline</h2>
                <br></br>
                <span>Normal position</span>
                <br></br>
                <span> </span>
                <br></br>
            </Text>

Кажется, короче, как ты думаешь? Я должен был бы избавиться от узла все же. Спасибо также за указание мне на PHP Sandbox.

Обновление

Я понимаю, C14N () меняет разметку. См <br /> до <br></br>.

...