循环遍历xml元素并显示在新行的表中?

时间:2016-02-28 16:10:10

标签: php xml domdocument

更新:

如何让这段代码显示在表格的每一行中。到目前为止,我已使用此表,并且我已尝试将此代码放在<td>之前和之内,但它不会将上述xml文件放到每个<cogxml>的新行中。你能看出我哪里错了吗?测试2.php是Parfait在答案中的PHP代码。

<?php
   include_once('test2.php');
?>


    <html>

    <head>
        <title>CharGer and CoGui</title>
        <link rel="stylesheet" type="text/css" href="../XSLT/myStyle.css" />
    </head>

    <body>
        <div style="overflow-x:auto;">
            <?php
            include_once("../XSLT/upload4.php");
            ?>
            <div class="wrap">
              <table>
                    <tr>
                        <th width="5%">Concept Name</th>
                        <th width="5%">Relation Type</th>
                        <th width="44%">CoGui XML</th>
                        <th width="46%">CharGer XML</th>
                    </tr>
                        <tr>
                        <?php
                      for ($x=0; $x <=5; $x++){?>
                            <td>

                            </td>
                            <td>

                            </td>
                            <td>

<pre><code class="language-xml"><?php echo htmlspecialchars(file_get_contents($xmlfile), ENT_QUOTES); ?></code></pre>


                            </td>
                            <td>
                            </td>

                        </tr>
                        <?php 
                      }
                        ?>
                </table>
             </div>
     </div>
   </body>
</html>

这就是目前的样子。它在每一行看起来像这样,但我只希望cogxml的每个部分出现在每一行中。 enter image description here

2 个答案:

答案 0 :(得分:1)

不是删除不匹配项,而是为每个<ctype>构建一个新文件。

要做到这一点,
 1.遍历所有<ctype>个节点  1.获取id - 属性,然后选择匹配
的所有<order><rtype>个节点  2.将结果复制到新的DOM。

遍历所有<ctype>个节点,获取id:

foreach ($dom->getElementsByTagName("ctype") as $ctype) {
    $id = $ctype->getAttribute('id');
    // more code will go here...
}

使用xpath

选择匹配项

设置xpath - 表达式:

/cogxml/support/conceptTypes/order[@id1='$id']

请注意,条件位于[]@信号attribute。在这种情况下,id1 - <order>节点的属性必须与$id匹配:

$xpath = new DOMXPath($dom);
$orders = $xpath->query("/cogxml/support/conceptTypes/order[@id1='$id']");

结果是DOMNodeList $orders,可能有0个或更多匹配。 与id - 节点的<rtype> - 属性匹配的相同过程。

构建一个新的DOM并将源节点复制到它

$newdom = new DOMDocument('1.0', 'utf-8');
$newdom->loadXML("<cogxml><support><conceptTypes /><relationTypes /></support></cogxml>");

这是设置基本的XML语料库。现在添加<ctype>及其我们选择的匹配节点 - importNode()将完成这项工作。请注意,我们需要新DOM中的父<conceptTypes>来调用appendChild

$newnode = $newdom->importNode($ctype, true);
$newdom->getElementsByTagName("conceptTypes")->item(0)->appendChild($newnode);

可能有多个匹配订单,因此我们迭代:

foreach ($orders as $order) {
    $newnode = $newdom->importNode($order, true);
    $newdom->getElementsByTagName("conceptTypes")->item(0)->appendChild($newnode);
}

复制$rtypes遵循相同的程序 最后,将新DOM保存到XML:

$newdom->saveXML("mynewfile.xml");

全部整理并精简:

$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadXML($x); // assume source XML in $x

$newdom = new DOMDocument('1.0', 'utf-8');
$xpath = new DOMXPath($dom);

foreach ($dom->getElementsByTagName("ctype") as $ctype) {

    $newdom->loadXML("<cogxml><support><conceptTypes /><relationTypes /></support></cogxml>");

    $newnode = $newdom->importNode($ctype, true);
    $newdom->getElementsByTagName("conceptTypes")->item(0)->appendChild($newnode);

    $id = $ctype->getAttribute('id');

    foreach ($xpath->query("/cogxml/support/conceptTypes/order[@id1='$id']") as $order) {
        $newnode = $newdom->importNode($order, true);
        $newdom->getElementsByTagName("conceptTypes")->item(0)->appendChild($newnode);
    }    

    foreach ($xpath->query("/cogxml/support/relationTypes/rtype[@id='$id']") as $rtype) {
        $newnode = $newdom->importNode($rtype, true);
        $newdom->getElementsByTagName("relationTypes")->item(0)->appendChild($newnode);
    }    

    echo $newdom->saveXML(); // echo to screen 
}

在行动中看到它:https://eval.in/527124

答案 1 :(得分:1)

如上所述,请考虑使用XSLT解决方案。具体来说,您需要使用ctype/@idMuenchian Grouping的XSLT。 PHP可以在单独的文件中处理外部调用的XSLT,也可以作为字符串嵌入。下面是前者:

XSLT 脚本(另存为.xsl或.xslt将在PHP中使用)

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

<xsl:key name="idkey" match="ctype" use="@id" />

  <xsl:template match="/">
    <root>
      <xsl:apply-templates select="*"/>
    </root>
  </xsl:template>

  <xsl:template match="ctype[generate-id() = generate-id(key('idkey',@id)[1])]">
    <xsl:variable select="@id" name="id"/>
    <cogxml>
      <support>
        <xsl:attribute name="name"><xsl:value-of select="ancestor::support/@name"/></xsl:attribute>            
        <conceptTypes>                    
          <xsl:copy>
            <xsl:copy-of select="@*"/>          
            <xsl:copy-of select="translation"/>
          </xsl:copy>
          <xsl:copy-of select="ancestor::conceptTypes/order[@id1=$id]"/>        
        </conceptTypes>      
        <relationTypes>
            <xsl:copy-of select="ancestor::support/relationTypes/rtype[contains(@idSignature, $id)]"/>
         </relationTypes>
      </support>
    </cogxml>
  </xsl:template>

</xsl:transform>

PHP 脚本

// Load the XML source and XSLT file
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$xml->load('Input.xml');

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

// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);
echo $newXML;

// Save output to file
$xmlfile = 'Output.xml';
file_put_contents($xmlfile, $newXML);

已转换的XML (由每个cType分隔)

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <cogxml>
    <support name="vocabulary">
      <conceptTypes>
        <ctype id="http://www.lirmm.fr/cogui#ct_043ea910-5f86-4150-b0f1-1418acf4db39" label="Junior Employee" x="250" y="10">
          <translation descr="" label="Junior Employee" lang="en"/>
        </ctype>
        <order id1="http://www.lirmm.fr/cogui#ct_043ea910-5f86-4150-b0f1-1418acf4db39" id2="http://www.lirmm.fr/cogui#ct_d7a78641-722f-4609-8f5a-90affc111e00"/>
      </conceptTypes>
      <relationTypes/>
    </support>
  </cogxml>
  <cogxml>
    <support name="vocabulary">
      <conceptTypes>
        <ctype id="http://www.lirmm.fr/cogui#ct_d7a78641-722f-4609-8f5a-90affc111e00" label="Employee" x="130" y="60">
          <translation descr="" label="Employee" lang="en"/>
        </ctype>
        <order id1="http://www.lirmm.fr/cogui#ct_d7a78641-722f-4609-8f5a-90affc111e00" id2="http://www.lirmm.fr/cogui#_ct_a12bacc5-bc88-429e-a7b1-45e143591288"/>
      </conceptTypes>
      <relationTypes/>
    </support>
  </cogxml>
  <cogxml>
    <support name="vocabulary">
      <conceptTypes>
        <ctype id="http://www.lirmm.fr/cogui#ct_feeca670-2f1c-433e-9271-4cffeda1e929" label="Director" x="250" y="110">
          <translation descr="" label="Director" lang="en"/>
        </ctype>
        <order id1="http://www.lirmm.fr/cogui#ct_feeca670-2f1c-433e-9271-4cffeda1e929" id2="http://www.lirmm.fr/cogui#ct_d7a78641-722f-4609-8f5a-90affc111e00"/>
      </conceptTypes>
      <relationTypes/>
    </support>
  </cogxml>
  <cogxml>
    <support name="vocabulary">
      <conceptTypes>
        <ctype id="http://www.lirmm.fr/cogui#ct_710bed80-a33e-4a13-b916-15fbb3357e8d" label="Manager" x="250" y="60">
          <translation descr="" label="Manager" lang="en"/>
        </ctype>
        <order id1="http://www.lirmm.fr/cogui#ct_710bed80-a33e-4a13-b916-15fbb3357e8d" id2="http://www.lirmm.fr/cogui#ct_d7a78641-722f-4609-8f5a-90affc111e00"/>
      </conceptTypes>
      <relationTypes/>
    </support>
  </cogxml>
  <cogxml>
    <support name="vocabulary">
      <conceptTypes>
        <ctype id="http://www.lirmm.fr/cogui#ct_cd84c648-ef22-4854-8e8c-a6654c0386be" label="Senior Employee" x="255" y="190">
          <translation descr="" label="Senior Employee" lang="en"/>
        </ctype>
        <order id1="http://www.lirmm.fr/cogui#ct_cd84c648-ef22-4854-8e8c-a6654c0386be" id2="http://www.lirmm.fr/cogui#ct_d7a78641-722f-4609-8f5a-90affc111e00"/>
      </conceptTypes>
      <relationTypes/>
    </support>
  </cogxml>
  <cogxml>
    <support name="vocabulary">
      <conceptTypes>
        <ctype id="http://www.lirmm.fr/cogui#_ct_a12bacc5-bc88-429e-a7b1-45e143591288" label="Top" x="10" y="60">
          <translation descr="" label="Top" lang="en"/>
        </ctype>
      </conceptTypes>
      <relationTypes>
        <rtype id="http://www.lirmm.fr/cogui#_rt_c42a5ce6-2f20-491d-8c91-501ae178a36c" idSignature="http://www.lirmm.fr/cogui#_ct_a12bacc5-bc88-429e-a7b1-45e143591288 http://www.lirmm.fr/cogui#_ct_a12bacc5-bc88-429e-a7b1-45e143591288" label="Link" x="10.0" y="10.0">
          <translation descr="" label="Link" lang="en"/>
        </rtype>
        <rtype id="http://www.lirmm.fr/cogui#rt_af40394c-9e62-4e92-b05b-352de5db876f" idSignature="http://www.lirmm.fr/cogui#_ct_a12bacc5-bc88-429e-a7b1-45e143591288 http://www.lirmm.fr/cogui#_ct_a12bacc5-bc88-429e-a7b1-45e143591288" label="senior" x="70.0" y="10.0">
          <translation descr="" label="senior" lang="en"/>
        </rtype>
      </relationTypes>
    </support>
  </cogxml>
</root>

要呈现HTML表,您可以扩展上面的XSLT脚本并保留精确的PHP脚本,但只需将输出保存为HTML:'Output.html'。回想一下,XSLT将XML转换为多种格式:XML,HTML甚至文本。这里<cogxml>将在表格的每一行中呈现。

HTML 表:

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

<xsl:key name="idkey" match="ctype" use="@id" />

  <xsl:template match="/">
     <html>

      <head>
        <title>CharGer and CoGui</title>
        <link rel="stylesheet" type="text/css" href="../XSLT/myStyle.css" />
      </head>

      <body>
        <div style="overflow-x:auto;">
          <div class="wrap">
              <table>
                    <tr>
                      <th width="5%">Concept Name</th>
                      <th width="5%">Relation Type</th>
                      <th width="44%">CoGui XML</th>
                      <th width="46%">CharGer XML</th>
                    </tr>
                      <xsl:apply-templates select="*"/>
              </table>
          </div>
        </div>
      </body>
     </html>

  </xsl:template>

  <xsl:template match="ctype[generate-id() = generate-id(key('idkey',@id)[1])]">
    <xsl:variable select="@id" name="id"/>
      <tr>
        <td>
        </td>
        <td>
        </td>
        <td>
          <pre>

          <cogxml>
            <support>
              <xsl:attribute name="name"><xsl:value-of select="ancestor::support/@name"/></xsl:attribute>            
              <conceptTypes>                    
                <xsl:copy>
                  <xsl:copy-of select="@*"/>          
                  <xsl:copy-of select="translation"/>
                </xsl:copy>
                <xsl:copy-of select="ancestor::conceptTypes/order[@id1=$id]"/>        
              </conceptTypes>      
              <relationTypes>
                  <xsl:copy-of select="ancestor::support/relationTypes/rtype[contains(@idSignature, $id)]"/>
               </relationTypes>
            </support>
          </cogxml>


          </pre>
        </td>
      </tr> 
  </xsl:template>

</xsl:transform>