如何将 div 包裹在现有元素周围?
How can I wrap a div around existing elements?
我正在尝试解析现有文档并通过将 div 包裹在一些现有表单元素周围来对其进行修改。
HTML 表格看起来有点像这样:
<form>
<label for="username">Username:</label>
<input name="username" type="text" />
<label for="password">Password:</label>
<input name="password" type="password" />
</form>
我可以用 Nokogiri 解析文档,我知道 wrap
方法,但我正在努力掌握如何 select 标签和输入标签一次性然后用 div 包裹这些。所以我要找的结果是:
<form>
<div class="form-group">
<label for="username">Username:</label>
<input name="username" type="text" />
</div>
<div class="form-group">
<label for="password">Password:</label>
<input name="password" type="password" />
</div>
</form>
我已经尝试了各种 XPaths / CSS select 或者可以创建仅 labels/inputs 或整个表单的所有元素的节点集。有什么办法可以实现这个修改吗?
单个 XPath 表达式只能 return 单个节点集合,因此为了实现您想要的结果,您需要进行多个查询,每个查询一个 label
– input
对.
你可以 select 像这样的一对,假设标记表现良好(即每个 input
前面都有一个 label
):
//label[1] | //label[1]/following-sibling::input[1]
这将 select 第一个 label
和接下来的 input
。但是你想要 select 所有这样的对。一种方法是首先 select 所有 label
节点,然后对每个 label
select 它和以下输入。
labels = doc.xpath("//form/label")
labels.each do |l|
nodes = l.xpath(". | ./following-sibling::input[1]")
# nodes now contains a label-input pair...
end
我认为 wrap
方法无法将 div
元素添加为每对元素的祖先,因为它会将元素添加到 each 节点集的成员。您可能需要手动移动它们,例如
labels = doc.xpath("//form/label")
labels.each do |l|
# Select this node and its neighbour.
nodes = l.xpath(". | ./following-sibling::input[1]")
# Create the new element, and add it before the label.
div = Nokogiri::XML::Node.new('div', l.document)
l.before(div)
# Move each of the pair onto this new element.
nodes.each do |n|
div.add_child(n)
end
end
请注意,此方法不会移动任何文本节点,因此您可能会发现文档的空白部分发生了一些变化。
我正在尝试解析现有文档并通过将 div 包裹在一些现有表单元素周围来对其进行修改。
HTML 表格看起来有点像这样:
<form>
<label for="username">Username:</label>
<input name="username" type="text" />
<label for="password">Password:</label>
<input name="password" type="password" />
</form>
我可以用 Nokogiri 解析文档,我知道 wrap
方法,但我正在努力掌握如何 select 标签和输入标签一次性然后用 div 包裹这些。所以我要找的结果是:
<form>
<div class="form-group">
<label for="username">Username:</label>
<input name="username" type="text" />
</div>
<div class="form-group">
<label for="password">Password:</label>
<input name="password" type="password" />
</div>
</form>
我已经尝试了各种 XPaths / CSS select 或者可以创建仅 labels/inputs 或整个表单的所有元素的节点集。有什么办法可以实现这个修改吗?
单个 XPath 表达式只能 return 单个节点集合,因此为了实现您想要的结果,您需要进行多个查询,每个查询一个 label
– input
对.
你可以 select 像这样的一对,假设标记表现良好(即每个 input
前面都有一个 label
):
//label[1] | //label[1]/following-sibling::input[1]
这将 select 第一个 label
和接下来的 input
。但是你想要 select 所有这样的对。一种方法是首先 select 所有 label
节点,然后对每个 label
select 它和以下输入。
labels = doc.xpath("//form/label")
labels.each do |l|
nodes = l.xpath(". | ./following-sibling::input[1]")
# nodes now contains a label-input pair...
end
我认为 wrap
方法无法将 div
元素添加为每对元素的祖先,因为它会将元素添加到 each 节点集的成员。您可能需要手动移动它们,例如
labels = doc.xpath("//form/label")
labels.each do |l|
# Select this node and its neighbour.
nodes = l.xpath(". | ./following-sibling::input[1]")
# Create the new element, and add it before the label.
div = Nokogiri::XML::Node.new('div', l.document)
l.before(div)
# Move each of the pair onto this new element.
nodes.each do |n|
div.add_child(n)
end
end
请注意,此方法不会移动任何文本节点,因此您可能会发现文档的空白部分发生了一些变化。