我正在制作一个材料明细表。我的XML父节点是我们正在制造的产品,子节点是BOM行,例如
<BOM>
<ProductName>This</ProductName>
<BOMLines>
<BOMLine>
<ProductCode>Widget-1</ProductCode>
<Qty>111</Qty>
</BOMLine>
<BOMLine>
<ProductCode>Widget-2</ProductCode>
<Qty>222</Qty>
</BOMLine>
<BOMLine>
<ProductCode>Widget-3</ProductCode>
<Qty>333</Qty>
</BOMLine>
</BomLines>
</BOM>
我的最终目标是使用 PHP 在每个 BOMLine 产品代码中插入一个 for 行以及父产品信息;
TABLE bom
id productCode lineCode qty
1 PROD-1 Widget-1 111
2 PROD-1 Widget-2 222
3 PROD-1 Widget-3 333
这是我到目前为止拥有的代码,但我无法让父信息以这种方式工作;
function updateBOM() {
$BOMXml = getBOMs('');
foreach ($BOMXml->BOM->BOMLines->BOMLine as $BOM) {
$BOMLine = $BOM->ProductCode;
$BOMQty = $BOM->Qty;
$ParentProduct = $BOMXML->BOM->ProductName
$sql = "INSERT INTO bom (productCode, lineCode, Qty) VALUES ('$ParentProduct', '$BOMLine', '$BOMQty')";
$retval = mysql_query($sql);
if(! $retval ) {
die('Could not enter data: ' . mysql_error());
}
$count += '1';
}
查询运行,我得到了一些数据,但每行的所有父产品都是空的:z
如果我以正确的方式理解您并基于您尝试的代码,我相信您可以通过以下方式获得父产品:
$BOMXml->BOM->ProductName
"之前"的 foreach 循环。
考虑使用两种声明性的专用语言:XSLT 和 SQL!由于MySQL提供了使用LOAD XML
命令直接将XML文件导入数据库表的工具,因此让PHP将原始XML转换为简化的平面结构以进行MySQL导入(其中转换后的节点与列名对齐(。
在这里,您可以避免迭代追加查询的任何循环。要运行 XSLT 1.0 脚本,PHP 需要.ini文件中启用php_xsl
扩展名。另外,请注意,因为mysql_*
是一个在 PHP 7 中完全删除的不推荐使用的库,SQL 调用使用假定为预初始化的 mysqli 库。享受调用两个引擎的乐趣:libxslt 和 MySQL!
PHP (带有嵌入式 XSLT 和 SQL 代码(
$doc = new DOMDocument();
$doc->load('Input.xml');
$xsl = new DOMDocument();
$xsl->loadXML('<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="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/BOM">
<data>
<xsl:apply-templates select="BOMLines"/>
</data>
</xsl:template>
<xsl:template match="BOMLine">
<row>
<productCode><xsl:value-of select="ancestor::BOM/ProductName"/></productCode>
<lineCode><xsl:value-of select="ProductCode" /></lineCode>
<qty><xsl:value-of select="Qty"/></qty>
</row>
</xsl:template>
</xsl:transform>');
// INITIALIZE AND CONFIGURE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// TRANSFORM XML SOURCE
$newXML = $proc->transformToXML($doc);
// SAVE CONTENT TO FILE
file_put_contents('/Output.xml', $newXML);
// RUN SQL COMMAND (IMPORTING FILE WITH FULL PATH REFERENCE)
$mysqli->query("LOAD XML LOCAL INFILE '/path/to/Output.xml'
INTO TABLE bom
ROWS IDENTIFIED BY '<row>';");