2017-02-02 7 views
3

私はPHPを初めて使用しています。xmlファイルがあり、PHPを使用してxmlファイル内の文を抽出して、文章を毎回3語に分解したいと考えています。文章は分割されます。
以下のXMLはXMLファイルのものです。

PHPを使用したXMLの中断文

<?xml version="1.0" encoding="utf-8" ?> 
<document> 
    <content> 
     <segment> 
      <sentence> 
       <word>Hi</word> 
       <word>there</word> 
       <word>people</word> 
       <word>I</word> 
       <word>want</word> 
       <word>to</word> 
       <word>introduce</word> 
       <word>you</word> 
       <word>to</word> 
       <word>my</word> 
       <word>world</word> 
      </sentence> 
      <sentence> 
       <word>Hi</word> 
       <word>there</word> 
       <word>people</word> 
       <word>I</word> 
       <word>want</word> 
       <word>to</word> 
       <word>introduce</word> 
       <word>you</word> 
       <word>to</word> 
       <word>my</word> 
       <word>world</word> 
      </sentence> 
     </segment> 
    </content> 
</document> 

出力は次のようになります。

Hi there people 
I want to 
introduce you to 
my world 
Hi there people 
I want to 
introduce you to 
my world 

私は、XML trannscriptを処理する関数を作成しました。

function loadTranscript($xml) { 
    $getfile = file_get_contents($xml); 
    $arr = simplexml_load_string($getfile); 
    foreach ($arr->content->segment->sentence as $sent) { 
     $count = str_word_count($sent,1); 
     $a=array_chunk($count,3); 
     foreach ($a as $a){ 
      echo implode(' ',$a); 
      echo PHP_EOL; 
     } 
    } 
} 

出力を生成できませんでした。 $sentは配列と見なされますか?私はXMLレベルで文章を壊したい。

+0

'$ GETFILE =のfile_get_contents($転写産物);' <それは実際に(afaict何もしていませんおそらく未設定の可変警告を生成することは別として)? – CD001

+0

私はXPathを見てみることをお勧めします - それはXML文書をナビゲートするためのきれいな方法です:http://www.w3schools.com/xml/xpath_syntax.aspそして、SimpleXMLとDOMDocumentの両方で使うことができます。 – CD001

答えて

1

$xmlは文字列かファイルパスですか?私はそれがこの答えの文字列であると考えています。

使用DOMDocument、それは

function loadTranscript($xml) { 
    $doc = new DOMDocument(); 
    $doc->loadXML($xml); 
    $words = $doc->getElementsByTagName('word'); 
    $i = 0; 
    foreach ($words as $word) { 
     if ($i >= 3) { 
      echo "\n";//it works on console. For browsers you should use echo "<br>"; 
      $i = 0; 
     } 
     echo $word->nodeValue.' '; 
     $i++; 
    } 
} 

私は別のforeach内のforeachを避けるために、余分な$iフラグを使用していますが、あなたのニーズにコードを適応させることができますが起こる作ります。

コメントの中で@ CD001が示唆しているように、以下は、複数のタグを考慮する新しいバージョンです<sentence>

function loadTranscript($xml) { 
    $doc = new DOMDocument(); 
    $doc->loadXML($xml); 
    $sentences = $doc->getElementsByTagName('sentence'); 
    foreach($sentences as $sentence) { 
     $words = $sentence->getElementsByTagName('word'); 
     $i = 0; 
     foreach ($words as $word) { 
      if ($i >= 3) { 
       echo "\n"; 
       $i = 0; 
      } 
      echo $word->nodeValue.' '; 
      $i++; 
     } 
     echo "\n"; 
    } 
} 

$doc->load('file/path/string.xml');

+0

2文を取得するまでは問題ありません。この場合、第2文の先頭が最初の文の末尾に追加されますが、DOMDocumentを使用する方法には同意します。SimpleXMLで作業するのは嫌です理由。 – CD001

+0

@ CD001 2文以上ではうまくいかないのですか?私のテストコード[ここ](http://sandbox.onlinephpfunctions.com/code/a409a071e78583c53f6dd9d58cdc2d268d5178d1)を参照してください。私はそれはうまく動作すると思うが、おそらく私はあなたのコメントを理解していない。はい、DomDocumentは私にとってもSimpleXMLよりはるかに優れています。 – James

+0

これはファイルパスです。 – kkbum

2

$doc->loadXML($xml);を置き換え、ファイルからXMLを読み取るために、誰もがSimpleXMLをのようにおびえている私はなぜわからない、と私はそれは間違いなく、この仕事のための適切なツールだと思います。

は配列ではなく、<sentence>要素とそのすべての子を表すオブジェクトです。それはいくつかの配列のような性質を持っていますが、array_chunkで動作するものはありません。

あなたが実際にarray_chunkを使用することができますが、あなたはあなたの現在のコードを動作させるために3つのことを行う必要があります。

  • の配列にすべての子供たちを与えるであろう((array)$sentを持つ配列へのオブジェクトから$sentをキャストarray_chunkにその配列内<word>と呼ばれるものに限らせて頂きます<sentence>ノード)または(array)$sent->word(、ケースには、混合物があった)
  • パス、ない$count(あなたが必要としない)
  • だから

相反する意味で二回(foreach($a as $a))を同じ変数を使用していない:

$chunks = array_chunk((array)$sent->word, 3); 
foreach ($chunks as $a_chunk) { 
    echo implode(' ', $a_chunk); 
    echo PHP_EOL; 
} 

を別の方法として、あなただけの改行ごとに第三の単語を表示することによって、簡単に十分なarray_chunkせずに行うことができます

$counter = 0; 
foreach ($words as $word) { 
    $counter++; 
    echo $word; 
    if ($counter % 3 == 0) { 
     echo PHP_EOL; 
    } else { 
     echo ' '; 
    } 
} 

次にあなたがする必要があるすべてはあなたの既存の内部にそのループの巣です:

foreach ($arr->content->segment->sentence as $sent) { 
    $counter = 0; 
    foreach ($sent->word as $word) { 
     $counter++; 
     echo $word; 
     if ($counter % 3 == 0) { 
      echo PHP_EOL; 
     } else { 
      echo ' '; 
     } 
    } 
    echo PHP_EOL; 
} 

あなたの意見はきれいだと思いますが、両方を理解しておくことで将来のニーズに対応できるようになります。

+1

それを怖がっていない - ちょうどそれが好きではない...私はDOMDocumentとXPathのソリューションを持っています - これは実際にはこれに非常に似ています...しかし、私はSimpleXMLを指定したので、投稿しないようにしています。代わりに+1することができます;) – CD001

+0

@ CD001のように、私はそれについて怖くはありません。それはちょうど...私には醜いですが、もちろん良い選択です。 +1 – James

+0

@ジェームズ怖い、嫌い、醜い、何でも;私はまだそれを取得しません。この ''の ''をループしたいので 'foreach($ sentence-> word as $ word)'と書いておきます。何が簡単だろうか?なぜ手動で複数の異なるヘルパーオブジェクトを作成し、それらの間の関係を管理したいのですか? *肩をすくめる*それぞれが自分のものだと思います。 – IMSoP

0

XML文書を変換するために設計された特別目的のW3C準拠言語(XPathから兄弟へ)のXSLTを検討してください。 XSLTはテキスト形式に変換できます。この手法では、foreachループまたはifロジックが不要です。 PHPは、.iniファイルで有効にする必要があるphp-xsl拡張子を組み込んだXSLT 1.0スクリプトを実行できます。 XSLTの美しさは、であり、整形式のXMLファイルであり、ファイルまたは埋め込み文字列からソースXMLのように解析できるということです。

具体的に、XSLTは、アイデンティティがノードなしであるように、各ノード<word>、テンプレートをチェックするための現在位置が改行を追加する3の倍数である場合に文書をコピーするを変換実行。最後に<word>の後に改行を追加します。 <xsl:output>の方法ものテキストであることに注意してください。

XSLT(の.xslとして保存)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" method="text"/> 
<xsl:strip-space elements="*"/> 

    <!-- Identity Transform --> 
    <xsl:template match="@*|node()">  
    <xsl:apply-templates select="@*|node()"/>  
    </xsl:template> 

    <xsl:template match="word">  
    <xsl:value-of select="concat(., ' ')"/> 
    <xsl:if test="(position() mod 3) = 0"> 
     <xsl:text>&#xa;</xsl:text> 
    </xsl:if> 
    <xsl:if test="position() = last()"> 
     <xsl:text>&#xa;</xsl:text> 
    </xsl:if> 
    </xsl:template> 

</xsl:transform> 

PHP

// LOAD XML AND XSL 
$xml = new DOMDocument(); 
$xml->load('Input.xml'); 

$xsl = new DOMDocument; 
$xsl->load('XSLTScript.xsl'); 

// INITIALIZE TRANSFORMER 
$proc = new XSLTProcessor; 
$proc->importStyleSheet($xsl); 

// RUN TRANSFORMATION 
$newXML = $proc->transformToXML($xml); 

// ECHO STRING OUTPUT 
echo $newXML; 

# Hi there people 
# I want to 
# introduce you to 
# my world 
# Hi there people 
# I want to 
# introduce you to 
# my world 
+0

おっと!ダウンボート! XSLTは難しいですか? – Parfait

+0

申し訳ありませんが、あなたがXSLTを知っていて、誰かに "ちょっと、あなたがPHPに苦しんでいるのを見て、その上に判読不能な専門用語を覚えてみてください。 – IMSoP

+0

あなたがXSLTがdownvoteの理由ではないのが好きではないからといって、許してください。 XSLTは、SQLによく似た特別目的の宣言言語です。これは、補完的な言語ではなく、置き換えられるものです。 SQLを使用せずにデータベースレコードを取得するのは嫌です。 – Parfait

関連する問題