重新访问XML名称空间问题

时间:2014-05-12 14:37:19

标签: regex perl libxml2

重新访问XML名称空间问题:

当我们让xmlns有一些值时,我仍然无法找到一个解决findnode或findvalue不起作用的问题的好方法。

我手动设置xmlns=""的那一刻,它开始工作。至少在我的情况下。现在我需要自动化。

考虑这个

< root xmlns="something" >
--
---
< /root>

我推荐的解决方案:

  1. 将值动态设置为xmlns=""

  2. 当工作自动完成后,我们可以重置为原始值xmlns="something"

  3. 这似乎只是我的XML的工作解决方案,但它的stll手册。

    我需要自动执行此操作:

    如何做2个选项:

    1. 使用Perl正则表达式,或

    2. 使用正确的LibXML setNamespace等。

    3. 请把你的想法放在这个背景下。

2 个答案:

答案 0 :(得分:1)

您注册名称空间。 XML的重点不在于使用正则表达式!

此外,更容易:您创建XML::LibXML::XPathContext,注册您的命名空间,并使用其所选前缀的find *调用。

以下示例逐字逐句地从我的脚本列出Visual Studio项目中的引用:

(...)
# namespace handling, see the XML::LibXML::Node documentation
my $xpc = new XML::LibXML::XPathContext;
$xpc->registerNs( 'msb',
   'http://schemas.microsoft.com/developer/msbuild/2003' );
(...)
my $tree; eval { $tree = $parser->parse_file($projfile) };
(...)
my $root = $tree->getDocumentElement;
(...)
foreach my $attr ( find( '//msb:*/@Include', $root ) )
{
   (...)
}
(...)
sub find { $xpc->find(@_)->get_nodelist; }
(...)

这就是全部!

答案 1 :(得分:1)

我只在XML的顶部有一个xmlns属性,所以这对我有用。

我所做的就是首先删除命名空间部分,即从我的XML文件中删除xmlns。

NODE : for my $node ($conn->findnodes("//*[name()='root']")) {

   my $att = $node->getAttribute('xmlns'); 

    $node->setAttribute('xmlns', ""); 

        last NODE;

}

使用 last 只是为了确保我及时来到for循环。

然后,一旦完成XML解析,我将替换

<root> 

<root xmlns="something">

使用简单的Perl文件操作或 sed 编辑器。