Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XML中的最新日期时间更新节点属性_Xml_Regex_Perl_Datetime - Fatal编程技术网

使用XML中的最新日期时间更新节点属性

使用XML中的最新日期时间更新节点属性,xml,regex,perl,datetime,Xml,Regex,Perl,Datetime,我有以下XML: < measCollecFile> < fileHeader> < measCollec beginTime="2013-03-14T12:10:00+00:00" /> </ fileHeader> < measData> < measInfo> < granPeriod dur

我有以下XML:

< measCollecFile>

    < fileHeader>

            < measCollec beginTime="2013-03-14T12:10:00+00:00" />

    </ fileHeader>

    < measData>

            < measInfo>
                    < granPeriod duration="PT300S" endTime="2013-03-14T12:15:00+00:00"  />
                    < measType>VS.ave</measType>
                    < measType>VS.aveCPU</measType>

                    < measValue>VS1</measValue>
                    < measValue>VS2</measValue>
            </ measInfo>
    </ measData>
</ measCollecFile>




VS.ave
VS
VS1
VS2
问:我的问题是,我需要处理这个XML文件并修改某些元素中的一些数据。我可以在这个网站的帮助下做到这一点,你可以从我以前的帖子中看到这一点

这是一个新的挑战。正如您所看到的,XML中也有datetime元素。我需要以XML中显示的格式将其更新为当前日期时间。i、 XML将始终包含任何日期,我只是想找到datetime标记并将其更新为当前datetime,但它的格式应与其中的格式相同

我是否应将其视为单独的问题,并将其视为简单的正则表达式Perl问题,并相应地作为平面文件解决查找和替换问题


或者,LIBXML内置了任何东西来标识日期时间标记并用最新的日期时间更新它?

没有什么特别的东西来标识您所指的“日期时间”标记。您当然可以寻找适合特定格式的属性,但这真的是您想要的吗

使用和将开始时间替换为当前日期:

use strict;
use warnings;

use XML::LibXML;
use Time::Piece;

my $date_format = '%Y-%m-%dT%H:%M:%S';

my $data = do { local $/; <DATA> };

my $dom = XML::LibXML->load_xml(string => $data);

for my $node ($dom->findnodes('//*[@beginTime]')) {
    if ( my $begin = $node->getAttribute('beginTime') ) {
        my ($plaindate, $tz) = split '(?=\+)', $begin;
        my $date = Time::Piece->strptime($plaindate, $date_format);
        print "old beginTime = '$date'\n";
        my $newdate = localtime->strftime($date_format);
        $node->setAttribute('beginTime', $newdate . $tz);
    }
}

print $dom->toString();

__DATA__
<measCollecFile>
    <fileHeader>
        <measCollec beginTime="2013-03-14T12:10:00+00:00" />
    </fileHeader>
    <measData>
        <measInfo>
            <granPeriod duration="PT300S" endTime="2013-03-14T12:15:00+00:00"  />
            <measType>VS.ave</measType>
            <measType>VS.aveCPU</measType>
            <measValue>VS1</measValue>
            <measValue>VS2</measValue>
        </measInfo>
    </measData>
</measCollecFile>

嗨,米勒。你太棒了!!这正是我想要的。唯一的问题是,开始时间和结束时间可能会多次出现,而且可能发生在不同的深度。但我会在手之前知道一些事情:什么是标签名,如beginTime、endTime等,以及日期时间的格式。希望findnode仍然能够在XML的各个深度找到所有的beginTime。我可能在开始时间和结束时间之间存在增量时间差,我需要始终保持这种差异。我提供的XPath将找到具有上述属性的所有节点。只要您可以编写所需的更改逻辑,这些逻辑就应该可以工作。不确定,但第二个逻辑在我同时包含两个节点qw(beginTime-endTime)的情况下不工作。“查找”节点找不到任何内容?哦,是的,它确实有效!实际上,我使用了parse_文件而不是load_xml。因为我还必须更新许多其他字段。看来我需要做两次,一次是用parse_file,下一次是用load_xml for datetime?加载xml的方法并不重要。我只是使用load_XML,因为它使我能够创建一个工作示例。
my @attribs = qw(beginTime endTime);
my $attribs_list = join ' | ', map {'@'.$_} @attribs;

for my $node ($dom->findnodes("//*[$attribs_list]")) {
    for my $key (@attribs) {
        if ( my $att = $node->getAttribute($key) ) {
            my ($plaindate, $tz) = split '(?=\+)', $att;
            my $date = Time::Piece->strptime($plaindate, $date_format);
            print "old $key = '$date'\n";
            my $newdate = localtime->strftime($date_format);
            $node->setAttribute($key, $newdate . $tz);
        }
    }
}