【问题标题】:Appending to XML file but its only appending to the first set of elements附加到 XML 文件,但它只附加到第一组元素
【发布时间】:2022-01-21 07:58:04
【问题描述】:

我有一个从另一个程序生成的 XML 文件,但我想附加到 XML 以便其他程序仍然可以读取数据。我编写了一个 PHP 脚本来简化应用程序,但我无法让它以我想要的方式工作。正如现在写的那样,我可以追加到 XML 文件,但它只会追加到第一组元素。

<?php
$file = "RouteSymbol.xml";
if (file_exists($file)) {
$orders = simplexml_load_file($file,"SimpleXMLElement", LIBXML_NOERROR |  LIBXML_ERR_NONE) or die("Error: Cannot create object");
echo "<table border='1'>";
 foreach ($orders->xpath(".//HighwayRoutingData") as $routingPoints){
    $tag=(string)$routingPoints->tag;
     echo "<tr>";
     echo "<td>".$tag."</td>";

     
     $stringArr =array();
     foreach($routingPoints->xpath(".//destinationSymbols//string") as $symbol){
     $string=(string)$symbol;

     $stringArr[] = $string;

}
$stringImp = implode(',', $stringArr);
echo "<td>";
echo  $stringImp;
echo "</td>";
echo "<td>";
?>
<form method="POST" action="addSymbol.php">
    <input type="text" name="symbol">
<?php
    echo '<input type="hidden" name="location" value="'.$tag.'">';
    echo '<input type="hidden" name="fileName" value="'.$file.'">';
    ?>
    <input type="submit" name="addSymbol" value="ADD">
</form>
<?php
echo "</td>";
echo "<td>";
echo "<a href='#'>Delete</a>";
echo "</td>";
echo "</tr>";  
}
echo "</table>";
}else{
            echo "Invalid request!";
        } 

附加代码

<?php 
$fileName = "";
if (isset($_POST['addSymbol'])) {
    $xml = new DomDocument();
    //$fileName = $_POST['fileName'];
    $xml->load('RouteSymbol.xml');

    $symbol = $_POST['symbol'];

    $rootTag = $xml->getElementsByTagName('destinationSymbols')->item(0);
    $symbolTag = $xml->createElement("string", $symbol);

    $rootTag->appendChild($symbolTag);
    $xml->save($_POST['fileName']);
    //echo $fileName;
    header("location:trainRouting.php");
}else{
    echo "Could not Load".$fileName;
}

我附加到的 XML 文件,现在脚本似乎只想附加到 @I80 目标符号。当它确实追加时,它也会追加到当前字符串标记集的右侧而不是下面

<?xml version="1.0"?>
<ArrayOfHighwayRoutingData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <HighwayRoutingData>
    <tag>@I80</tag>
    <destinationSymbols>
      <string>SFO</string>
      <string>OAK</string>
      <string>EMR</string>
      <string>ELC</string>
      <string>RIC</string>
      <string>SPB</string>
    <string>HER</string><string>HER</string></destinationSymbols>
  </HighwayRoutingData>
    <HighwayRoutingData>
    <tag>@SR24</tag>
    <destinationSymbols>
      <string>OAK</string>
      <string>ORI</string>
      <string>LFY</string>
      <string>WCR</string>
    </destinationSymbols>
  </HighwayRoutingData>
  <HighwayRoutingData>
    <tag>@US101</tag>
    <destinationSymbols>
      <string>SFO</string>
      <string>SSC</string>
      <string>MIL</string>
      <string>PAO</string>
    </destinationSymbols>
  </HighwayRoutingData>

  </ArrayOfHighwayRoutingData>

如果有帮助,有一个代码笔https://codepen.io/dsflyerds/pen/BawZzMx

【问题讨论】:

  • 您需要显示添加数据的代码以提供帮助。
  • I would like to append to the XML - 附加新内容的代码在哪里?我看到上面读取了现有文件并生成了 HTML 输出,但我看不到 XML 的附加或修改
  • 顺便说一句,上面读取 XMl 并生成 HTML 内容的代码可以使用 XSLT 样式表来完成?
  • @ProfessorAbronsius 对不起,我忘了包括它。它现在在那里
  • 提交表单时,您希望向每个HighwayRoutingData 部分添加一个新元素,还是根据表单元素中提供的值添加到特定部分?

标签: php html xml


【解决方案1】:

我对表单用于update XML 的方式做了一个假设,因此不是为每个表行/HighwayRoutingData 节点使用单独的表单,单个表单与使用 array 语法一起就足够了字段名称。

我假设根据 XML 和 HTML 表中分配的 tag,将写入文本字段的任何文本附加到 XML 中的相关 destinationSymbols 节点,而不是附加到 ALL @987654326 @节点。然而,修改该行为是相当简单的。您会注意到没有 SimpleXML 函数,因为我从未使用过它,所以它只是使用 DOMDocument 和 DOMXPath。

<?php

    error_reporting( E_ALL );
    /*
        We should ONLY proceed if these POST fields
        are actually set.
    */
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset(
        $_POST['location'],
        $_POST['fileName'],
        $_POST['symbol']
    )){

        /*
            Prepare filters
        */
        $args=array(
            'symbol'    =>  array('filter' => FILTER_SANITIZE_ENCODED, 'flags' => FILTER_REQUIRE_ARRAY ),
            'location'  =>  array('filter' => FILTER_SANITIZE_ENCODED, 'flags' => FILTER_REQUIRE_ARRAY ),
            'fileName'  =>  FILTER_SANITIZE_ENCODED
        );
        /*
            modify the POST array based upon the filters and
            extract the values directly into variables.
        */
        $_POST=filter_input_array( INPUT_POST, $args );
        extract( $_POST );




        /*
            set options for dealing with XML. 
        */
        libxml_use_internal_errors( true ) ;
        $dom=new DOMDocument('1.0','UTF-8');
        $dom->recover=true;
        $dom->formatOutput=true;
        $dom->preserveWhiteSpace=false;
        $dom->validateOnParse=false;
        $dom->strictErrorChecking=false;
        $dom->load( urldecode( $fileName ) );

        $xp=new DOMXPath( $dom );

        
        /*
            Iterate through all POSTed items
        */
        foreach( $symbol as $index => $code ){
            /* Locate the relevant section within the XML based upon the tag */
            $loc=urldecode( $location[ $index ] );
            $expr=sprintf( '//HighwayRoutingData/tag[ contains( text(), "%s") ]', urldecode( $loc ) );
            $col=$xp->query( $expr );
            
            /* create the new symbol and add to the relevant `destinationSymbols` node */
            if( $col && $col->length > 0 && !empty( $code ) ){
                $symbol=$dom->createElement( 'string', $code );
                $dest=$xp->query( 'destinationSymbols', $col->item(0)->parentNode )->item(0);
                $dest->appendChild( $symbol );
            }
        }
        /* save the XML and redirect? */
        $dom->save( urldecode( $fileName ) );
    }
?>
    
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Simple XML Processing...</title>
    </head>
    <body>
        <!-- 
            a single form should be OK and there is no need to repeat the
            `fileName` element as this is the same for each row in the table.
        -->
        <form method='post'>
            <table border=1 cellpadding='5px' cellspacing='2px'>
                <tr>
                    <th>Tag</th>
                    <th>Strings</th>
                    <th colspan=3>&nbsp;</th>
                </tr>
                <?php
                    
                    $file='RouteSymbol.xml';
                
                    libxml_use_internal_errors( true ) ;
                    /*
                        Load the XML file and build the HTML output
                    */
                    $dom=new DOMDocument();
                    $dom->validateOnParse=false;
                    $dom->recover=true;
                    $dom->strictErrorChecking=false;
                    $dom->load( $file );
                    libxml_clear_errors();
                    
                    
                    $xp=new DOMXPath( $dom );
                    $col=$xp->query('//HighwayRoutingData');
                    
                    
                    if( $col && $col->length > 0 ){
                        foreach( $col as $node ){
                            /*
                                find the `string` values and add to an array
                                which we will use to build a string later.
                            */
                            $output=array();
                            $strings=$xp->query( 'destinationSymbols/string', $node );
                            foreach( $strings as $string )$output[]=$string->nodeValue;
                            
                            /*
                                Find the tag for this node.
                            */
                            $tag=$xp->query('tag',$node)->item(0)->nodeValue;
                            
                            /*
                                Generate a new HTML table row with data found in this
                                node of the xml.
                            */
                            printf('
                                <tr>
                                    <td>%1$s</td>
                                    <td>%2$s</td>
                                    <td>
                                        <input type="text" name="symbol[]" />
                                        <input type="hidden" name="location[]" value="%1$s" />
                                    </td>
                                    <td><input type="submit" value="ADD" /></td>
                                    <td><a href="#delete">Delete</a></td>
                                </tr>',
                                $tag,
                                implode( ', ', $output )
                            );
                        }
                    }
                ?>
            </table>
            <input type='hidden' name='fileName' value='<?=$filename;?>' />
        </form>
    </body>
</html>

【讨论】:

  • 我查看了代码,但仍然无法弄清楚为什么将空白字符串附加到我不打算附加到的标签上。 IE 如果我将符号添加到第一个标签区域,它会将&lt;string&gt;&lt;/string&gt; 添加到其余标签类别
  • 哎呀 - 对不起。现在更正了代码。 preserveWhiteSpace 应该设置为 false 并且为了防止添加空元素,我只是在调用 createElement 之前添加/忘记添加 `&& !empty( $code )`
猜你喜欢
  • 2018-11-09
  • 2016-10-05
  • 2016-11-03
  • 2021-04-30
  • 2021-05-16
  • 2013-05-13
相关资源
最近更新 更多