如何使用php修改XML文件的特定信息并生成新的XML

laawzig2  于 2023-04-19  发布在  PHP
关注(0)|答案(1)|浏览(147)

我有一个由标签打印机应用程序生成的XML文件,我的问题是编辑“pt:data”的正确方法是使用SimpleXMLElement还是其他更有效的方法。

<pt:body currentSheet="Folha 1" direction="LTR">
<style:sheet name="Folha 1">
<pt:objects>
<barcode:barcode>
<pt:data>text1</pt:data>
</barcode:barcode>
<text:text>
<text:textControl control="FREE" clipFrame="false" aspectNormal="false" shrink="false" autoLF="false" avoidImage="false"/>
<text:textAlign horizontalAlignment="JUSTIFY" verticalAlignment="CENTER" inLineAlignment="BASELINE"/>
<text:textStyle vertical="false" nullBlock="false" charSpace="0" lineSpace="0" orgPoint="6pt" combinedChars="false"/>
<pt:data>text2</pt:data>
<text:stringItem charLen="1"></text:stringItem>
</text:text>
<text:text><pt:data>text3</pt:data></text:text>
</pt:objects></style:sheet>
</pt:body>

目标是将“text1”,“text2”和“text3”更改为“item1”,“item2”和“item3”,在屏幕上显示结果并生成一个具有不同名称的新文件,例如:“1edit.xml”
使用SimpleXMLElement和registerXPathNamespace,我至少能够在屏幕上显示内容。

<?php
$xml=<<<XML
<book xmlns:pt="http://example.org/1">  
    
    <pt:body currentSheet="Folha 1" direction="LTR">
    <style:sheet name="Folha 1">
    <pt:objects>
    <barcode:barcode>
    <pt:data>text1</pt:data>
    </barcode:barcode>
    <text:text>
        <text:textControl control="FREE" clipFrame="false" aspectNormal="false" shrink="false" autoLF="false" avoidImage="false"/>
        <text:textAlign horizontalAlignment="JUSTIFY" verticalAlignment="CENTER" inLineAlignment="BASELINE"/>
        <text:textStyle vertical="false" nullBlock="false" charSpace="0" lineSpace="0" orgPoint="6pt" combinedChars="false"/>
        <pt:data>text2</pt:data>
        <text:stringItem charLen="1"></text:stringItem>
    </text:text>
    <text:text><pt:data>text3</pt:data></text:text>
        </pt:objects></style:sheet>
        </pt:body>
    

</book>
XML;

$sxe=new SimpleXMLElement($xml);
$sxe->registerXPathNamespace('p', 'http://example.org/1');
$result=$sxe->xpath('//p:data');
foreach ($result as $title)
  {
  echo $title . "<br>";
  }
?>

为了解释为什么XML具有这种格式:
有问题的XML文件是由工业机器的系统生成的,改变其结构会使机器无法读取。
最终的目的是,通过一个有8个文本字段的PHP表单,执行解压缩.LBX文件,从里面提取XLM文件,加载,更新为表单数据,并重新组装.LBX文件与内部更改的XML的功能。
我能够让PHP解压缩LBX文件(使用ZipArchive类),加载和读取XML(使用我演示的逻辑),并重新压缩包含XML的LBX文件(使用ZipArchive类)。我仍然没有成功地更新XML,同时保持其原始结构。这就是为什么我来这里向大家寻求帮助。
enter image description here

tcomlyy6

tcomlyy61#

我通过添加一些人为的名称空间声明来“修复”示例XML,使其成为格式良好的XML。
XSLT1.0解决方案有点冗长。
在XSLT2.0及更高版本中,它只是一行调用replace()函数。

输入XML

<?xml version="1.0"?>
<pt:body currentSheet="Folha 1" direction="LTR" xmlns:pt="ns1" xmlns:style="ns2" xmlns:barcode="ns3" xmlns:text="ns4">
    <style:sheet name="Folha 1">
        <pt:objects>
            <barcode:barcode>
                <pt:data>text1</pt:data>
            </barcode:barcode>
            <text:text>
                <text:textControl control="FREE" clipFrame="false" aspectNormal="false" shrink="false" autoLF="false" avoidImage="false"/>
                <text:textAlign horizontalAlignment="JUSTIFY" verticalAlignment="CENTER" inLineAlignment="BASELINE"/>
                <text:textStyle vertical="false" nullBlock="false" charSpace="0" lineSpace="0" orgPoint="6pt" combinedChars="false"/>
                <pt:data>text2</pt:data>
                <text:stringItem charLen="1"></text:stringItem>
            </text:text>
            <text:text>
                <pt:data>text3</pt:data>
            </text:text>
        </pt:objects>
    </style:sheet>
</pt:body>

XSLT 1.0

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pt="ns1" xmlns:style="ns2" xmlns:barcode="ns3"
                xmlns:text="ns4">
    <xsl:output method="xml" indent="yes" encoding="utf-8"
                omit-xml-declaration="no"/>
    <xsl:strip-space elements="*"/>

    <!--Identity Transform pattern-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="pt:data/text()">
        <!--<xsl:value-of select="replace(.,'text','item')"/>-->
        <xsl:call-template name="replace-string">
            <xsl:with-param name="text" select="."/>
            <xsl:with-param name="replace" select="'text'"/>
            <xsl:with-param name="with" select="'item'"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="replace-string">
        <xsl:param name="text"/>
        <xsl:param name="replace"/>
        <xsl:param name="with"/>
        <xsl:choose>
            <xsl:when test="contains($text,$replace)">
                <xsl:value-of select="substring-before($text,$replace)"/>
                <xsl:value-of select="$with"/>
                <xsl:call-template name="replace-string">
                    <xsl:with-param name="text"
                                    select="substring-after($text,$replace)"/>
                    <xsl:with-param name="replace" select="$replace"/>
                    <xsl:with-param name="with" select="$with"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

输出XML

<?xml version='1.0' encoding='utf-8' standalone='no' ?>
<pt:body xmlns:pt="ns1" currentSheet="Folha 1" xmlns:style="ns2" xmlns:barcode="ns3" xmlns:text="ns4" direction="LTR">
  <style:sheet name="Folha 1">
    <pt:objects>
      <barcode:barcode>
        <pt:data>item1</pt:data>
      </barcode:barcode>
      <text:text>
        <text:textControl control="FREE" clipFrame="false" aspectNormal="false" shrink="false" autoLF="false" avoidImage="false"/>
        <text:textAlign horizontalAlignment="JUSTIFY" verticalAlignment="CENTER" inLineAlignment="BASELINE"/>
        <text:textStyle vertical="false" nullBlock="false" charSpace="0" lineSpace="0" orgPoint="6pt" combinedChars="false"/>
        <pt:data>item2</pt:data>
        <text:stringItem charLen="1"/>
      </text:text>
      <text:text>
        <pt:data>item3</pt:data>
      </text:text>
    </pt:objects>
  </style:sheet>
</pt:body>

相关问题