要仅在某个子树内计算 XPath 表达式,libxml2 函数xmlXPathNodeEval()似乎是最佳选择。该文档指定XPath 表达式是在“给定上下文中”计算的。但这究竟意味着什么呢?
考虑下面的小例子:
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xmlstring.h>
#include <stdio.h>
int main(int argc, char **argv)
{
const char inp[] =
"<root>\n"
" <sub>\n"
" <e>0</e>\n"
" <Foo>\n"
" <e>1</e><e>2</e><e>3</e>\n"
" <FooSub><e>3a</e></FooSub>\n"
" </Foo>\n"
" <Bar>\n"
" <e>4</e><e>5</e><e>6</e>\n"
" </Bar>\n"
" </sub>\n"
" <e>7</e>\n"
"</root>\n";
xmlDoc *doc = xmlParseMemory(inp, sizeof(inp)-1);
xmlXPathContext *ctx = xmlXPathNewContext(doc);
xmlXPathObject *p = xmlXPathEval(BAD_CAST "//Foo[1]", ctx);
xmlNode *new_root = *p->nodesetval->nodeTab;
printf("New root: %s\n", BAD_CAST new_root->name);
xmlXPathObject *q = xmlXPathNodeEval(new_root, …Run Code Online (Sandbox Code Playgroud) 我在使用 XML::LibXML 时遇到一些问题,我想知道是否有办法做我想做的事情,或者是否应该更改我的 XML。
目前,我的 XML 如下所示:
<fftg>
<actions>
<rename>
<mandatory>0</mandatory>
<other_things_here />
</rename>
<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<other_things_here />
</transfer>
<transfer>
<mandatory>1</mandatory>
<protocol>FTP</protocol>
<other_things_here />
</transfer>
<archive>
<mandatory>1</mandatory>
<other_things_here />
</archive>
<rename>
<mandatory>1</mandatory>
<other_things_here />
</rename>
</actions>
</fftg>
Run Code Online (Sandbox Code Playgroud)
如您所见,在“actions”下,可以有不同类型的操作(每种操作有 1 个或多个操作,每个操作下有不同的内容)
我想浏览每个操作并根据该操作执行特定的操作。
我的问题是:由于存在多个同类操作,因此脚本无法正常工作并覆盖前一个同类操作,或者特定操作上的循环会在同类每个操作上重新循环
示例1:
foreach my $transfer ($doc->findnodes('/fftg')) {
# Browse Actions
foreach my $action ($doc->findnodes('/fftg/actions/*')) {
my $action_name = $action->nodeName();
my $actiontype = ucfirst($action->nodeName());
print "executing action $action_name ..\n";
# Browse action details
foreach my $action_details ($doc->findnodes('/fftg/actions/'.$action_name)) {
for …Run Code Online (Sandbox Code Playgroud) 我正在使用go-libxml2进行 xsd 架构验证。我有一个 XML 元素,它将 url 作为值。我的 xsd 还包含其类型为 anyURI,如下
<xs:element name="url" type="xs:anyURI">
Run Code Online (Sandbox Code Playgroud)
以下代码在包含“[]”的验证网址上引发错误
xsd.schema.Validate(xml)
Run Code Online (Sandbox Code Playgroud)
以下是引发错误的示例 url
<url>
<![CDATA[
http://example.com/orda/var[div]=super
]]>
</url>
Run Code Online (Sandbox Code Playgroud)
错误:
'http://example.com/orda/var[div]=super is not a valid value of the atomic type 'xs:anyURI'
Run Code Online (Sandbox Code Playgroud)
常规网址工作正常。知道如何解决这个问题
我正在用C++编写一个关于libxml2的小包装器,我正在尝试解决如何处理错误.现在,让我们说我只想打印出来.这是我目前得到的:
我的错误处理功能:
void foo(void *ctx, const char *msg, ...) {
cout << msg << endl;
return;
}
Run Code Online (Sandbox Code Playgroud)
初始化如下:
xmlGenericErrorFunc handler = (xmlGenericErrorFunc)foo;
initGenericErrorDefaultFunc(&handler);
Run Code Online (Sandbox Code Playgroud)
但是,如果我解析一个糟糕的XPath,我得到这个输出:
%s
没有错误处理代码,我得到这个:
XPath error : Invalid expression
//.@foobar
^
显然,最终我的错误处理将不仅仅打印出错误消息(它会将其记录到数据库或其他东西),但是现在 - 我怎样才能获得该错误字符串?
我正在使用libxml2解析XML文件,我需要从xml属性中提取一个十六进制数.现在,lib2xml没有为属性提供一个以空字符结尾的字符串,只是指向属性的开头和结尾.
因此,给定.........FILL:BB0011AA;............... (其中点表示任意字符),并char* begin指向F in FILL,并char* end指向分号,如何有效地拉出十六进制数,而不将副本复制为空终止字符串?
考虑以下.为什么sizeof返回"23"?我怎样才能得到真正的尺寸?(不算嘿)
char defaultsettings[] = "<?xml version=\"1.0\"?>\n";
strcat(defaultsettings, "<CsSettings>\n<options>\n");
strcat(defaultsettings, "<spin name=\"maxTries\" value=\"1000\" />\n");
strcat(defaultsettings, "<spin name=\"rollCount\" value=\"1\" />\n");
strcat(defaultsettings, "<check name=\"matchItems\" value=\"1\" />\n");
strcat(defaultsettings, "<check name=\"highlightItems\" value=\"1\" />\n");
strcat(defaultsettings, "<check name=\"buyListMode\" value=\"0\" />\n");
strcat(defaultsettings, "<radio name=\"matchItemType\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"matchLocations\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"highlightLocations\" value=\"1\" />\n");
strcat(defaultsettings, "<check name=\"allMissionsSameLocation\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"highlightFind\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"highlightReturn\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"highlightRepair\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"highlightPerson\" value=\"0\" />\n");
strcat(defaultsettings, "<check name=\"highlightKill\" value=\"0\" />\n");
strcat(defaultsettings, "<check …Run Code Online (Sandbox Code Playgroud) 我有以下内容:
my $string='<entry><name>Bob</name><zip>90210</zip></entry>';
my $parser=XML::LibXML->new();
use HTML::Entities;
my $encodedXml=encode_entities($string,'&\'');
my $doc=$parser->parse_string($encodedXml);
foreach my $text($doc->findnodes("//text()")){
print $text->to_literal,"\n";
}
Run Code Online (Sandbox Code Playgroud)
这打印出'Bob'和'90210';
我如何获得实际的节点名称...我需要一种方法来获取我的xml树中的所有节点....即'name'和'zip'
我正在使用XML :: LibXML,我想添加一个注释,使得注释不在标记之内.甚至可以把它放在标签之外?我试过appendChild,insertBefore | 之后,没有区别......
<JJ>junk</JJ> <!--My comment Here!-->
# Code excerpt from within a foreach loop:
my $elem = $dom->createElement("JJ");
my $txt_node = $dom->createTextNode("junk");
my $cmt = $dom->createComment("My comment Here!");
$elem->appendChild($txt_node);
$b->appendChild($elem);
$b->appendChild($frag);
$elem->appendChild($cmt);
# but it puts the comment between the tags ...
<JJ>junk<!--My comment Here!--></JJ>
Run Code Online (Sandbox Code Playgroud) 我基本上是模块的新手,我试图在我的脚本中使用它们.我无法找到正确使用它们的正确方法,我想了解你的建议.
让我快速解释一下我要做的事情:
我的脚本正在根据XML文件中的数据进行一些文件传输.
所以基本上,我有XML文件,内容如下:
<fftg>
<actions>
<!-- Rename file(s) -->
<rename>
<mandatory>0</mandatory>
<file name="foo" to="bar" />
</rename>
<!-- Transfer file(s) -->
<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<server>fqdn</server>
<port>22</port>
<file name="bar" remotefolder="toto" />
</transfer>
<!-- Transfer file(s) -->
<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<server>fqdn</server>
<port>22</port>
<file name="blabla" remotefolder="xxxx" />
<file name="blabla2" remotefolder="xxxx" />
</transfer>
</actions>
</fftg>
Run Code Online (Sandbox Code Playgroud)
简而言之,我有一个执行"动作"的脚本.每个动作都可以重复X次.
现在,而不是一个重要的脚本与一堆子程序等..我认为为我的应用程序创建模块应该更好,并将操作放在模块中.
例如 :
FFTG::Rename
FFTG::Transfer
FFTG::Transfer::SFTP
FFTG::Transfer::FTP
Run Code Online (Sandbox Code Playgroud)
等等(我创建了所有这些模块,它们可以独立工作)
并根据XML文件中指定的操作调用这些模块.如果需要,人们可以创建新的模块/操作(我希望模块化).
现在,我不知道如何正确地做到这一点.
所以我的问题是:请问最好的方法是什么?
目前,我的脚本正在阅读这些动作:
# Load XML file
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($FFTG_TSF . "/" . $tid …Run Code Online (Sandbox Code Playgroud) 有这样的XML文件 - t.xml
<?xml version="1.0"?>
<ArrayOfFiles xmlns="Our.Files" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<File>
<DownloadCount>1</DownloadCount>
<Id>11</Id>
</File>
<File>
<DownloadCount>2</DownloadCount>
<Id>22</Id>
</File>
</ArrayOfFiles>
Run Code Online (Sandbox Code Playgroud)
该xmlns声明是无效的,在xmlstarlet抱怨它,例如使用:
xmlstarlet sel -t -v "//File/Id" t.xml
Run Code Online (Sandbox Code Playgroud)
版画
t.xml:2.32: xmlns: URI Our.Files is not absolute
<ArrayOfFiles xmlns="Our.Files" xmlns:i="http://www.w3.org/2001/XMLSchema-instan
Run Code Online (Sandbox Code Playgroud)
可能出于同样的原因,我也无法使用以下perl代码:
use 5.014;
use warnings;
use XML::LibXML;
my $dom = XML::LibXML->new->parse_file('t.xml');
my $res = $dom->findnodes('//File/Id');
say $_->textContent for $res->get_nodelist;
Run Code Online (Sandbox Code Playgroud)
当我省略xmlns声明时,例如尝试解析这个修改过的XML文件
<?xml version="1.0"?>
<ArrayOfFiles>
<File>
<DownloadCount>1</DownloadCount>
<Id>11</Id>
</File>
<File>
<DownloadCount>2</DownloadCount>
<Id>22</Id>
</File>
</ArrayOfFiles>
Run Code Online (Sandbox Code Playgroud)
上面的代码DWIM - 并打印:
11
22
Run Code Online (Sandbox Code Playgroud)
问题是,如何解析原始XML文件,因为它是从外部站点下载的 …