我正在使用PHP,我想删除特定标记内的所有标记并仅保留纯文本。我坚持的问题是,有一些子标签与父标签的名称相同:
<corpo>
<num>1.</num>
<mod id="mod167">
String 1
<commas id="mod167-vir1" type="word">String 2</commas>
<com id="mod166-vir1-20090024-art13-com16.1"><num><<16.</num></com>
<rif xlink:href="urn" xlink:type="simple">String 3</rif><h:p>Something here</h:p>
<corpo>String 4</corpo>
</mod>
</corpo>
例如,corpo
具有同名的子标记(<corpo>String 4</corpo>
),num
标记使用了两次(<num>1.</num>
和{{1} }})在父标记<num><<16.</num>
内。
从最高corpo
标记开始,我想删除每个子标记并仅保留纯文本。结果应该是:
corpo
到目前为止,我尝试使用SimpleXML和PHP <corpo>
String 1 String 2 <<16. String 3 Something here String 4
</corpo>
添加了我想要保留的所有标记,但当然它没有给出我期望的结果。
strip_tags
答案 0 :(得分:1)
如果将XML加载到DOM中,则可以阅读DOMNode::$textContent
属性。
$document = new DOMDocument();
$document->loadXml($xml);
var_dump($document->documentElement->textContent);
输出包含文本内容,包括所有空格。
string(113) "
1.
String 1
String 2
<<16.
String 3Something here
String 4
"
在更复杂的结构中,使用Xpath获取值。函数normalize-space()
将第一个节点强制转换为字符串,删除前导和尾随空格,并将所有其他空白组转换为单个空格。
$xpath = new DOMXpath($document);
var_dump($xpath->evaluate('normalize-space(/corpo)'));
输出:
string(58) "1. String 1 String 2 <<16. String 3Something here String 4"
要创建包含已删除标记的XML,请导入不带子项的corpo
节点并附加文本内容:
$target = new DOMDocument();
foreach ($xpath->evaluate('/corpo') as $corpo) {
$target
->appendChild(
$target->importNode($corpo)
)->appendChild(
$target->createTextNode(
$xpath->evaluate('normalize-space(.)', $corpo)
)
);
}
echo $target->saveXml();
输出:
<?xml version="1.0"?>
<corpo xmlns:xlink="urn:xlink" xmlns:h="urn:h">1. String 1 String 2 <<16. String 3Something here String 4</corpo>
答案 1 :(得分:1)
这与@ThW编写的内容非常相关,更侧重于SimpleXML。我还在xpath上显示了一些不同的角度来选择公司元素。
如果文档中的字符$buffer
与字符$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//corpo[not(ancestor::corpo)]') as $corpo) {
$corpo[0] = dom_import_simplexml($corpo)->textContent;
}
$xml->asXML('php://output');
相同或更多,那么这是一个XML示例:
<a xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:h="ns:h">
<b>
<corpo>
1.
String 1
String 2
<<16.
String 3
Something here
String 4
</corpo>
</b>
</a>
其示例性输出是:
//corpo[not(ancestor::corpo)]
它的工作原理如下:
获取每个 corpo 元素,该元素没有具有该名称的祖先。这是由xpath:
完成的$corpo
然后,因为这是一个 SimpleXMLElement ,并且您想要文本内容,可以通过dom_import_simplexml($corpo)->textContent;
关联的 DOMElement 节点访问它:
$corpo[0] = ...
剩下的表达
strip_tags($corpo->asXML())
告诉您更新 SimpleXMLElement 的内容(所谓的自引用)。
BTW你可以在这里使用dom_import_simplexml($corpo)->textContent
代替strip_tags
,但我不会建议,因为我不知道preg_replace
到底有多稳定。它至少不符合XML标准。
现在你可能也想要应用一些空格规范化,因为foreach ($xml->xpath('//corpo[not(ancestor::corpo)]') as $corpo) {
$text = dom_import_simplexml($corpo)->textContent;
$corpo[0] = preg_replace('~\s+~u', ' ', $text);
}
对于UTF-8标志很方便,这是 SimpleXMLElement 和 DOMElement使用的字符串编码强>:
<?xml version="1.0"?>
<a xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:h="ns:h">
<b>
<corpo> 1. String 1 String 2 <<16. String 3 Something here String 4 </corpo>
</b>
</a>
此变体为您提供:
<?php
$buffer = <<<XML
<a xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:h="ns:h">
<b>
<corpo>
<num>1.</num>
<mod id="mod167">
String 1
<commas id="mod167-vir1" type="word">String 2</commas>
<com id="mod166-vir1-20090024-art13-com16.1">
<num><<16.</num>
</com>
<rif xlink:href="urn" xlink:type="simple">String 3</rif>
<h:p>Something here</h:p>
<corpo>String 4</corpo>
</mod>
</corpo>
</b>
</a>
XML;
$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//corpo[not(ancestor::corpo)]') as $corpo) {
$text = dom_import_simplexml($corpo)->textContent;
$corpo[0] = preg_replace('~\s+~u', ' ', $text);
}
$xml->asXML('php://output');
完整示例一览Demo:
WITH myCTE AS
(
Your Query here!!!
)
SELECT *, furtherData
FROM myCTE