我有以下XML(这只是标题):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tmx SYSTEM "tmx14.dtd">
<tmx version="1.4">
<header creationtool="TDC Analysis Package" creationtoolversion="org.gs4tr.tm3.tmx.Version" segtype="sentence" o-tmf="unknown" adminlang="EN-US" srclang="EN" datatype="unknown" creationdate="20221006T184234Z">
    <prop type="x-Recognizers">RecognizeAll</prop>
    <prop type="x-IncludesContextContent">True</prop>
    <prop type="x-TMName">sample_tmx.tmx</prop>
    <prop type="x-TokenizerFlags">DefaultFlags</prop>
    <prop type="x-WordCountFlags">DefaultFlags</prop>
</header>

我需要首先判断type属性为‘x-TMName’的prop node 是否存在.(有些文件有它,有些没有.)如果它存在,我需要更新它.如果它不存在,我需要创建它.

我使用SimpleXML解析这些文件.一开始,我用的是这个:

if(isset($xmlObj->header->prop[2])) { 
    $TM_name = $xmlObj->header->prop[2];
}

要访问它和更新它,请执行以下操作:

$xmlObj->header->prop[2] = $new_TM_name;

然而,这并不可靠,因为第三位可能会有不同的prop.所以,在大量阅读和实验之后,我设法判断了它是否存在,并像这样阅读:

$fileName = "INVERTED_sample_tmx.tmx";

/* read TMX file contents */
$uploadedFile = "user_files/".$fileName;
$xmlStr = file_get_contents($uploadedFile);
$xmlObj = simplexml_load_string($xmlStr);

/* extract <header> <prop>s */
$props = $xmlObj->header->prop;
/* loop them to check if the type='x-TMName' attribute exists */
foreach($props as $prop) {
    $type = (string)$prop->attributes()->type;
    /* if exists, assign its value to the $TM_name variable */
        if($type == "x-TMName") {
            $TM_name = $prop;
            //$new_TM_name = "INVERTED ".$TM_name;
            //var_dump($prop);
        }
}

如果type属性为‘x-TMName’的prop node 不存在,即如果$TM_name变量未设置,我将创建它:

if(isset($TM_name)) {
    $new_TM_name = "INVERTED ".$TM_name;
    echo "Old TM name is ".$TM_name." and new TM name is ".$new_TM_name;
}
else {
    /* use the fileName as the TM name */
    $new_TM_name = "INVERTED ".$fileName;
    if($new_prop = $xmlObj->header->addChild('prop', $new_TM_name)) {
        $new_prop->addAttribute('type', "x-TMName2");
        echo "new prop added";
    }
}

这种方法的问题是我不能用$new_TM_name更新 node ,因为我不知道如何访问它.当我试图用$prop = $new_TM_name在上面的foreach循环中更新它时,页面陷入了无休止的打印循环.我也不知道如何在foreach循环之外访问它.我试过了:

$headerProps = $xmlObj->header->prop['x-TMName']
or
$headerProps = $xmlObj->header->prop->{'x-TMName'}
or
$headerProps = (string)$xmlObj->header->prop->attributes()->type->{'x-TMName'};
var_dump($headerProps);

这些打印都是空的.编辑:虽然我的问题现在已经解决了,但我仍然不明白为什么上面的方法(S)不能 Select 我想要的元素,我必须使用foreach循环.我在这里找到了几十个答案,它们提供了类似于我的问题的答案.有没有人能解释一下他们哪里不对劲?编辑结束.

我对使用XML和SimpleXML非常陌生,我一直在阅读,但我似乎就是找不到正确的方法.请帮帮忙.

推荐答案

据我所知,创建一个新对象正如您所预期的那样,所以主要问题似乎是更新现有 node 的值(如果它存在的话).

这个版本使用了SimpleXML的一个‘功能’,它允许您在引用元素本身的同时设置XML元素的值.

在循环中,$prop将是一个SimpleXMLElement对象,因此要设置该对象的值(而不是将$prop设置为变量),您可以使用$prop[0]...

foreach($props as $prop) {
    /* if exists, assign its value to the $TM_name variable */
    if((string)$prop['type'] == "x-TMName") {
        $TM_name = (string)$prop;
        // Update the node value
        $prop[0] = "INVERTED ".$TM_name;
    }
}

你可以使用循环来查找元素,而不仅仅是使用一个循环.它看起来简单得多-但然后你需要开始学习网络,这是一个全新的学习领域.

Php相关问答推荐

无法添加ProxyClass__setInitialized()上的忽略

composer如何解析包名?

按制造商、型号和年份范围判断数据的存在性

Laravel关系-为用户获取属于组织的所有团队

让所有具有相同名称的产品在WooCommerce中更改价格

创建一个新的可变产品及其属性以用于WooCommerce中的变体

允许在WooCommerce管理员优惠券列表中显示自定义优惠券类型

在WooCommerce中的本地收件发货方式下添加一个 Select 字段

添加并显示单价字段到WooCommerce产品变化

在PHP中使用curl命令执行SCRAPYD操作.json不返回任何内容

使用与OpenSSL命令行兼容的AES-256-CTR为大型文件创建php代码OpenSSL加密

模式 bootstrap 未显示

根据发货类别在WooCommerce产品页面中显示快捷代码

即使在WooCommerce购物车中添加了两次产品,也要将所有项目设置为空白行

为什么PHP PDO忽略NOT NULL约束?

产品页面自定义复选框可对 WooCommerce 购物车小计启用百分比折扣

Shopware 6 AuthControllerDecorator已弃用

自定义主键值未正确显示

按数字然后按字符串对关联 PHP 数组进行排序

PHP - 如何获取发送到脚本的查询参数