首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从XML元素中删除开始和结束空格

从XML元素中删除开始和结束空格
EN

Stack Overflow用户
提问于 2011-09-08 01:26:04
回答 3查看 9K关注 0票数 5

如何删除XML字段前后的所有空格字符?

代码语言:javascript
复制
<data version="2.0">

  <field> 

     1 

  </field>        

  <field something=" some attribute here... "> 

     2  

  </field>

</data>

请注意,1和2前的空格和“这里的一些属性...”,我想用PHP删除它。

代码语言:javascript
复制
if(($xml = simplexml_load_file($file)) === false) die();

print_r($xml);

此外,数据似乎不是字符串,我需要在每个变量之前附加(字符串)。为什么?

EN

回答 3

Stack Overflow用户

发布于 2011-09-08 01:33:15

您可能想要使用下面这样的内容:

代码语言:javascript
复制
$str = file_get_contents($file);
$str = preg_replace('~\s*(<([^>]*)>[^<]*</\2>|<[^>]*>)\s*~','$1',$str);
$xml = simplexml_load_string($xml,'SimpleXMLElement', LIBXML_NOCDATA);

我还没有尝试过,但你可以在http://www.lonhosford.com/lonblog/2011/01/07/php-simplexml-load-xml-file-preserve-cdata-remove-whitespace-between-nodes-and-return-json/上找到更多关于这个的信息。

注意,开始和结束括号(<x> _space_ </x>)和属性(<x attr=" _space_ ">)之间的空格实际上是XML文档数据的一部分(与<x> _space_ <y>之间的空格形成对比),因此我建议您使用的源应该少一些空格。

票数 2
EN

Stack Overflow用户

发布于 2011-09-08 01:29:14

由于simplexml_load_file()将数据读入数组,因此您可以这样做:

代码语言:javascript
复制
function TrimArray($input){

    if (!is_array($input))
        return trim($input);

    return array_map('TrimArray', $input);
}
票数 1
EN

Stack Overflow用户

发布于 2015-08-04 01:47:11

要在PHP中做到这一点,首先必须将文档转换为DOMDocument,这样您就可以通过DOMXPath正确地定位要在其中规范化空格的节点。(中的xpath) SimpleXMLElement太过有限,无法精确地访问文本节点,因为该操作需要它。

要访问叶元素中的所有文本节点和所有属性的Xpath查询为:

代码语言:javascript
复制
//*[not(*)]/text() | //@*

鉴于$xml是一个SimpleXMLElement,您可以像下面的示例那样进行空白规范化:

代码语言:javascript
复制
$doc   = dom_import_simplexml($xml)->ownerDocument;
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//*[not(*)]/text()|//@*') as $node) {
    /** @var $node DOMText|DOMAttr */
    $node->nodeValue = trim(preg_replace('~\s+~u', ' ', $node->nodeValue), ' ');
}

您也许可以将其扩展到所有文本节点(as suggested in related Q&A),但在这种情况下可能需要对文档进行规范化。由于Xpath中的text()在文本节点和Cdata节之间没有区别,因此您可能希望在加载文档时跳过这些类型的节点()或将它们扩展为文本节点(使用the LIBXML_NOCDATA option实现),以获得更有用的结果。

同样,数据看起来不是字符串,我需要在每个变量的前面加上(字符串)。为什么?

因为它是一个SimpleXMLElement,类型的对象,如果您想要这样一个对象(元素)的String值,就需要将它转换为string。另请参阅以下参考问题:

最后但并非最不重要的一点是:当您在SimpleXMLElement:上使用print_rvar_dump时,不要信任它们,它们不会显示事实。例如,您可以覆盖__toString(),这也可以解决您的问题:

代码语言:javascript
复制
class TrimXMLElement extends SimpleXMLElement
{
    public function __toString()
    {
        return trim(preg_replace('~\s+~u', ' ', parent::__toString()), ' ');
    }
}

$xml = simplexml_load_string($buffer, 'TrimXMLElement');

print_r($xml);

即使转换为字符串可以正常应用(例如,使用echo),print_r的输出仍然不会反映这些更改。所以最好不要依赖它,它永远不会显示整个画面。

此答案的完整示例代码(Online Demo):

代码语言:javascript
复制
<?php
/**
 * Remove starting and ending spaces from XML elements
 *
 * @link https://stackoverflow.com/a/31793566/367456
 */

$buffer = <<<XML
<data version="2.0">

  <field>

     1

  </field>

  <field something=" some attribute here... ">

     2 <![CDATA[ 34 ]]>

  </field>

</data>
XML;

class TrimXMLElement extends SimpleXMLElement implements JsonSerializable
{
    public function __toString()
    {
        return trim(preg_replace('~\s+~u', ' ', parent::__toString()), ' ');
    }

    function jsonSerialize()
    {
        $array = (array) $this;

        array_walk_recursive($array, function(&$value) {
            if (is_string($value)) {
                $value  = trim(preg_replace('~\s+~u', ' ', $value), ' ');
            }
        });

        return $array;
    }
}

$xml = simplexml_load_string($buffer, 'TrimXMLElement', LIBXML_NOCDATA);

print_r($xml);
echo json_encode($xml);

$xml = simplexml_load_string($buffer, null, LIBXML_NOCDATA);

$doc = dom_import_simplexml($xml)->ownerDocument;
$doc->normalizeDocument();
$doc->normalize();

$xpath = new DOMXPath($doc);
foreach ($xpath->query('//*[not(*)]/text()|//@*') as $node) {
    /** @var $node DOMText|DOMAttr|DOMCdataSection */
    if ($node instanceof DOMCdataSection) {
        continue;
    }
    $node->nodeValue = trim(preg_replace('~\s+~u', ' ', $node->nodeValue), ' ');
}

echo $xml->asXML();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7337992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档