2011-09-07 15 views
5

मैं XML क्षेत्र से पहले और बाद में सभी अंतरण वर्णों को कैसे हटा सकता हूं?XML तत्वों से प्रारंभ और समाप्ति रिक्त स्थान निकालें

<data version="2.0"> 

    <field> 

    1 

    </field>   

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

    2 

    </field> 

</data> 

ध्यान दें कि 1 और 2 से पहले अंतर और 'यहां कुछ विशेषता ...', मैं इसे PHP से हटाना चाहता हूं।

if(($xml = simplexml_load_file($file)) === false) die(); 

print_r($xml); 

डेटा भी स्ट्रिंग प्रतीत नहीं होता है, मुझे प्रत्येक चर से पहले (स्ट्रिंग) जोड़ना होगा। क्यूं कर?

+1

कृपया http://stackoverflow.com/questions/8200582/remove-newline-from-xml-element- पर मेरा उत्तर देखना मूल्य/8200664 # 8200664 एक संभावित समाधान के लिए – Gordon

उत्तर

1

simplexml_load_file() के बाद से एक सरणी में डेटा पढ़ता है, आप कुछ इस तरह कर सकता है:

function TrimArray($input){ 

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

    return array_map('TrimArray', $input); 
} 
+0

नहीं, यह किसी सरणी में डेटा नहीं पढ़ता है, लेकिन यह इसमें से ** SimpleXMLElement ** बनाता है। और वह ऑब्जेक्ट स्ट्रिंग में हो सकता है (जो तब होता है जब आप उस पर 'ट्रिम' कहते हैं)। – hakre

1

आप कुछ इस तरह का उपयोग करना चाहते हो सकता है:

$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> के बीच रिक्त स्थान के साथ तुलना में), तो मैं सुझाव है कि आप का उपयोग स्रोत रिक्त स्थान के साथ थोड़ा कम गन्दा होना चाहिए।

0

कि PHP में आपको पहले एक DOMDocument में दस्तावेज़ कन्वर्ट करने के लिए इतना है कि आप नोड्स आप DOMXPath के माध्यम से ठीक से भीतर खाली स्थान के सामान्य करना चाहते हैं को संबोधित कर सकते हैं ऐसा करने के लिए। (Xpath in) SimpleXMLElement टेक्स्ट-नोड्स तक पहुंचने के लिए बहुत सीमित है क्योंकि इस ऑपरेशन के लिए इसकी आवश्यकता होगी।

एक Xpath-क्वेरी सभी पाठ नोड्स पत्ती-तत्वों के भीतर कर रहे हैं और सभी विशेषताओं का उपयोग करने के लिए है:

//*[not(*)]/text() | //@* 

यह देखते हुए कि $xml एक SimpleXMLElement है आप की तरह सफेद-अंतरिक्ष सामान्य कर सकता है निम्न उदाहरण:

$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() टेक्स्ट-नोड्स और सीडीटा-सेक्शन के बीच भिन्न नहीं है, इसलिए आप इस प्रकार के नोड्स (DOMCdataSection) पर छोड़ना चाहते हैं या दस्तावेज लोड करते समय टेक्स्ट-नोड्स में विस्तार करना चाहते हैं (इसके लिए the LIBXML_NOCDATA option का उपयोग करें) और अधिक उपयोगी प्राप्त करने के लिए परिणाम है।


इसके अलावा डेटा स्ट्रिंग होने के लिए प्रकट नहीं होता है, मैं प्रत्येक चर से पहले संलग्न करने के लिए (स्ट्रिंग) की जरूरत है। क्यूं कर?

क्योंकि यह प्रकार SimpleXMLElement का एक उद्देश्य है, अगर आप इस तरह के एक वस्तु (तत्व) का स्ट्रिंग मान चाहते हैं, आप स्ट्रिंग के लिए यह कास्ट करने के लिए की जरूरत है।साथ ही देखें निम्न संदर्भ प्रश्न:


और अंत में कम से कम: print_r या var_dump पर भरोसा नहीं करते जब आप एक SimpleXMLElement पर इसका इस्तेमाल: इसके प्रदर्शित न होने सच्चाई। जैसे आप __toString() रद्द कर सकते थे जो भी आपकी समस्या का समाधान हो सकता है:

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):

<?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(); 
संबंधित मुद्दे