如何在XML中连接类似的标记

时间:2014-10-24 06:13:02

标签: php mysql xml

请帮我编码。 @hakre

我有以下XML文件。

<?xml version="1.0"?>
  <Results>
    <Recordset setCount="3">

      <Record setEntry="0">
        <TI>Test-1</TI>
        <MO>Mo-1</MO>
        <AU>One</AU>
        <AU>Two</AU>
        <AU>three</AU>
        <JF>OK</JF>
        <JT />
      </Record>

      <Record setEntry="1">
        <TI>Test-2</TI>
        <MO>Mo-2</MO>
        <AU>One</AU>
        <AU>Two</AU>
        <AU>Three</AU>
        <AU>Four</AU>
        <AU>Five</AU>
        <AU>Six</AU>
        <AU>Seven</AU>
        <JF />
        <JT />
      </Record>

      <Record setEntry="2">
        <TI>Test31</TI>
        <MO>Mo-3</MO>
        <AU>One</AU>
        <AU />
        <JF />
        <JT />
      </Record>

    </Recordset>
  </Results>

我希望它像下面的XML文件。

<?xml version="1.0"?>
  <Results>
    <Recordset setCount="3">

      <Record setEntry="0">
        <TI>Test-1</TI>
        <MO>Mo-1</MO>
        <AU>One; Two; Tree</AU>
        <JF>OK</JF>
        <JT />
      </Record>

      <Record setEntry="1">
        <TI>Test-2</TI>
        <MO>Mo-2</MO>
        <AU>One; Two; Three; Four; Five; Six; Seven</AU>
        <JF />
        <JT />
      </Record>

      <Record setEntry="2">
        <TI>Test31</TI>
        <MO>Mo-3</MO>
        <AU>One</AU>
        <JF />
        <JT />
      </Record>

    </Recordset>
  </Results>

这些是我需要完成的事情。

  1. 将SIMILAR XML标记中的值连接成一个标记,用&#34;;&#34;分隔。 (&#34; AU标签&#34;在给定的例子中)

  2. 保留空白的XML标记。

  3. PHP以名称&#34; SECOND.XML&#34;创建和保存第二个XML文件。

1 个答案:

答案 0 :(得分:0)

这是解决问题的一种方法。它不会硬编码任何子节点名称(TIMOAU等),因此您可能会在类似文档上使用它。我在代码中添加了注释,因此请阅读它们并询问您是否不理解代码的作用。

$txt = 'your XML string goes here';
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($txt);

$xp = new DOMXPath($dom);

# find all the nodes types that appear under Record
$cnode_type = array();
foreach ($xp->query("/Results/Recordset/Record/*") as $c) {
    $cnode_type[] = $c->nodeName;
}
# cnode_type now contains the different child node types
$cnode_type = array_unique($cnode_type);

# get all the Record nodes
$recs = $xp->query("/Results/Recordset/Record");

# for every Record node...
foreach ($recs as $par) {
    # for each type of child node...
    foreach ($cnode_type as $c) {
        # run an XPath query to count the number of children of node type $c
        # if there are more than one, we need to remove the extras
        if ($xp->evaluate("count($c)", $par) > 1) {
            # go through all the $c nodes, saving the value in $node_vals
            # delete the node
            $node_vals = [];
            foreach ($xp->query($c, $par) as $n) {
                # only save the contents of nodes with a value
                if (isset($n->nodeValue) && strlen($n->nodeValue) > 0) {
                    $node_vals[] = $n->nodeValue;
                }
                $par->removeChild($n);
            }
            # create a new $c node and set the value to the list in $node_vals
            # add it to the parent node
            $new_node = $dom->createElement($c, implode("; ", $node_vals));
            $par->appendChild($new_node);
        }
    }
}
# print out the result
echo $dom->saveXML();

您发布的XML的输出:

<?xml version="1.0"?>
<Results>
  <Recordset setCount="3">
    <Record setEntry="0">
      <TI>Test-1</TI>
      <MO>Mo-1</MO>
      <JF>OK</JF>
      <JT/>
      <AU>One; Two; three</AU>
    </Record>
    <Record setEntry="1">
      <TI>Test-2</TI>
      <MO>Mo-2</MO>
      <JF/>
      <JT/>
      <AU>One; Two; Three; Four; Five; Six; Seven</AU>
    </Record>
    <Record setEntry="2">
      <TI>Test31</TI>
      <MO>Mo-3</MO>
      <JF/>
      <JT/>
      <AU>One</AU>
    </Record>
  </Recordset>
</Results>