【问题标题】:PHP document model: Finding an element in a composed HTML documentPHP 文档模型:在组合的 HTML 文档中查找元素
【发布时间】:2018-06-17 19:13:58
【问题描述】:

我有一个使用 DOM 类组成 HTML 元素的库。我还想使用 DOM 功能深入了解我的组合元素并检查特定子元素的值。

例如,这里的元素由名为YesNoControl 的类生成:

<div id="yes_no">
  <input id="yes_no_1" name="yes_no" value="1" type="radio"/>
  <label for="yes_no_1">Yes</label>
  <input id="yes_no_2" name="yes_no" value="2" type="radio"/>
  <label for="yes_no_2">No</label>
</div>

PHPUnit 测试应如下所示:

$element = new YesNoControl();

$element_dom = $element->toDOMDocument(); // This method renders the object to a DOMDocument object.
$element_dom->validate();
$this->assertInstanceOf(\\DOMDocument::class, $element_dom);

$input = $element_dom->getElementById('yes_no_1');
$this->assertInstanceOf(\DOMNode::class, $input); 
$this->assertEquals('1', $input->getAttribute('yes_no_1'));

问题是$input 总是返回null

在我的研究中,我发现getElementById() 仅在文档​​具有 DOCTYPE HTML 标记时才有效。在我的构建器中,我以简单明了的方式创建文档:

$document = new \DOMDocument();

我尝试在创建文档后直接将实现标签添加到文档中:

$implementation = new \DOMImplementation();
$document->appendChild($implementation->createDocumentType('HTML'));

但是,这会产生错误插入 &lt;!DOCTYPE HTML&gt; 的无效元素,如下例:

<div id="yes_no">
  <!DOCTYPE HTML>
  <input id="yes_no_1" name="yes_no" value="1" type="radio"/>
  <label for="yes_no_1">Yes</label>
  <input id="yes_no_2" name="yes_no" value="2" type="radio"/>
  <label for="yes_no_2">No</label>
</div>

我看到很多答案都提到将&lt;!DOCTYPE HTML&gt; 放入被解释的 HTML 中(例如this one)。但我不是从 HTML 开始的;我正在编写一个元素并让 DOM 库编写 HTML。

我还尝试根据this answer 即时创建一个实现:

$element_dom = $element->toDOMDocument(); // This method renders the object to a DOMDocument object.
$element_dom->validate();

$dtd = '<!ELEMENT input (#PCDATA)>';
$systemId = 'data://text/plain;base64,'.base64_encode($dtd);
$implementation = new \DOMImplementation;
$element_dom->appendChild($$implementation->createDocumentType('HTML', null, $systemId));

$input = $element_dom->getElementById('yes_no_1');
$this->assertInstanceOf(\DOMNode::class, $input); 
// Failed asserting that null is an instance of class "DOMNode".

我也尝试过使用 XPath 来获取值:

$xpath = new \DOMXPath($element_dom);
$input = $xpath->query("//*[@id=yes_no_1]")->item(0);
$this->assertInstanceOf(\DOMNode::class, $input); 
// Failed asserting that null is an instance of class "DOMNode".

到目前为止,我没有尝试过任何工作。我需要如何构建我的测试以便它可以找到yes_no_1

【问题讨论】:

  • 在您的 XPath 版本中 - 您需要在要检查的值周围加上引号 - //*[@id='yes_no_1']
  • 解决了这个问题。添加您的评论作为答案,我会选择它。

标签: php dom


【解决方案1】:

在您的 XPath 版本中 - 您需要在要检查的值周围加上引号

$input = $xpath->query("//*[@id='yes_no_1']")->item(0);

【讨论】:

    猜你喜欢
    • 2017-04-10
    • 2016-04-14
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多