在 php 中将大型 XML 文件拆分为较小的部分


Split large XML files into smaller pieces in php

如何更准确地将大型 xml 文件拆分为较小的文件,我希望每个节点都有一个 xml 文件,并且 xml 文件的名称由子 fron 节点提供。

XML 文件具有以下结构

<Products>
  <Products>
    <ID>ID</ID>
    <Name>Product_Name</Name>
    <Qty>qty</Qty>
    <Brand>Brand</Brand>
     ......
  </Product>
  <Product>
    <ID>ID</ID>
    <Name>Product_Name</Name>
    <Qty>qty</Qty>
    <Brand>Brand</Brand>
     ......
  </Product>
  <Product>
   ........
  </Product>
</Products>

我在互联网上搜索过,我只找到了 c# 解决方案,我不知道 c#

所以我需要为每个产品提供一个 XML 文件,并且 xml 文件的名称由 <ID></ID> 中的值给出

你应该用 DomDocument 和 XPath 做点什么尝试使用://Product[./ID/text()="ID2"] 或只是//Product

您可以使用 XSL(T)(也可能不使用,具体取决于服务器配置)。
libxslt 的当前版本仍然是 xsl 1.0,不支持 xsl:result-document
但它支持exsl:document扩展,其目的几乎相同。

<?php
$xsl = new XSLTProcessor;
$xsl->setSecurityPrefs(
    $xsl->getSecurityPrefs() ^ XSL_SECPREF_WRITE_FILE
);

$xsl->importStylesheet( doc(style()) );
$doc = doc( data() );
$xsl->transformToXML($doc);
function doc($xml) {
    $doc = new DOMDocument;
    $doc->loadxml($xml);
    return $doc;
}
function style() {
    return <<< eox
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:exsl="http://exslt.org/common"
                extension-element-prefixes="exsl">
  <xsl:template match="/">
    <xsl:for-each select="Products/Product">
        <exsl:document href="Product{ID}.xml" method="html">
            <Product>
                <xsl:apply-templates />
            </Product>
        </exsl:document>
        </xsl:for-each>
  </xsl:template>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
eox;
}
function data() {
    return <<< eox
<Products>
    <Product>
        <ID>ID1</ID>
        <Name>Product_Name1</Name>
        <Qty>qty1</Qty>
        <Brand>Brand1</Brand>
    </Product>
    <Product>
        <ID>ID2</ID>
        <Name>Product_Name2</Name>
        <Qty>qty2</Qty>
        <Brand>Brand2</Brand>
    </Product>
    <Product>
        <ID>ID3</ID>
        <Name>Product_Name3</Name>
        <Qty>qty3</Qty>
        <Brand>Brand3</Brand>
    </Product>
    <Product>
        <ID>ID4</ID>
        <Name>Product_Name4</Name>
        <Qty>qty4</Qty>
        <Brand>Brand4</Brand>
    </Product>
</Products>
eox;
}

在我的机器上创建四个文件(产品ID1.xml ...产品ID4.xml ),每个都包含一个产品元素的数据。
XsltProcessor::setSecurityPrefs相对较新。您的脚本应检查 xsl 实例是否具有此类方法,如果没有,则改为使用 ini_set('xsl.security_prefs'...) 禁用"写保护"。否则,您可能会得到一堆

Warning: XSLTProcessor::transformToXml(): File write for ProductID1.xml refused in ...test.php on line ...

警告/错误。
也许而不是<Product><xsl:apply-templates />结构<xsl:copy-of select="."/>更适合。