在 perl xpath find 语句中使用变量

发布于 2024-10-08 06:46:57 字数 898 浏览 0 评论 0原文

好吧,我一直在四处寻找,似乎找不到我的问题的答案。我正在使用 Perl 通过 XPATH 解析 XML 文件。文件的一部分,我不知道子节点将被命名为什么。例如:

<state xmlns="http://google.com" id=1>
  <randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id=2>
  <randomName2 type="boolean">1</randomName2>
</state>

因此,对于每个 randomName,我需要通过执行以下代码来获取我能够获取的名称(注意:我在父 foreach 语句中获取节点列表)。

my $elements = $nodes->getChildNodes;

foreach my $element(@$elements)
{
my $name = (lc($element->getName))
}

当我尝试获取值时,我的问题出现了,我尝试将 my $value = $element->string_value; 放入 foreach 循环中,而所做的只是返回 0,无论姓名。我还尝试在 xpath string_value 语句中放置一个变量,但没有成功。

有没有办法将变量放入 xpath 表达式中?类似于(注意:这不起作用)我的 $value = $element->find('$name')->string_value;

抱歉,如果不清楚,我会尝试回答任何问题,但我们将不胜感激任何帮助,我已经花了更多时间来尝试解决这个问题。

Ok, i've been searching around and can't seem to find an answer for my problem. I'm using Perl to parse an XML file using XPATH. Part of the file, I don't know what the child nodes will be named. For example:

<state xmlns="http://google.com" id=1>
  <randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id=2>
  <randomName2 type="boolean">1</randomName2>
</state>

So for each randomName, I need to grab the name which I was able to do by doing the following code (note: I grab the nodelist in a parent foreach statement).

my $elements = $nodes->getChildNodes;

foreach my $element(@$elements)
{
my $name = (lc($element->getName))
}

My issue comes comes in when I try to grab the value, I attempted to put my $value = $element->string_value; inside of the foreach loop and all that did was return 0 no matter the name. I also tried putting a variable in the xpath string_value statement with no luck.

Is there a way to put a variable in an xpath expression? Something simliar to (note: this doesn't work) my $value = $element->find('$name')->string_value;?

Sorry, if that's not clear and i'll try to answer any questions but any help would be greatly appreciated, I've already spent more time on trying to figure this out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

内心激荡 2024-10-15 06:46:57

问题是,如果文档位于默认命名空间中,则仅在位置步骤中使用元素名称将不会选择任何内容,因为 XPath 将所有无前缀的名称视为“无命名空间”。 这是XPath中最常见的FAQ。只需搜索“XPath默认命名空间”即可获得答案。

有两种解决方案

  1. 在类似“NamespaceManager”的对象中注册命名空间,然后然后在 XPath 表达式中使用前缀

  2. 使用如下位置步骤*[name()='someName']

The problem is that if a document is in a default namespace just using an element name in a location step will select nothing, because XPath treats all unprefixed names to be in "no namespace". This is the most FAQ in XPath. Just search for "XPath default namespace" to get the answer.

There are two solutions:

  1. Register the namespace in a "NamespaceManager" -like object and then use the prefix in the XPath expression.

  2. Use a location step like: *[name()='someName']

清风挽心 2024-10-15 06:46:57

我建议使用 XML::XPath 模块:

use XML::XPath;
use XML::XPath::XMLParser;

my $xp = XML::XPath->new(filename => 'test.xml');
my $nodeset = $xp->find('/states/state/*'); # find all subnodes

foreach my $node ($nodeset->get_nodelist) {
    print "FOUND: ", XML::XPath::XMLParser::as_string($node), "\n";
}

在这个示例 XML 文件中:

<?xml version="1.0"?>

<states>
<state xmlns="http://google.com" id="1">
  <randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id="2">
  <randomName2 type="boolean">1</randomName2>
</state>
</states>

这段代码打印:

FOUND: <randomName1 type="boolean">0</randomName1>
FOUND: <randomName2 type="boolean">1</randomName2>

perl+cpan 太棒了!

I recommend the use of XML::XPath module:

use XML::XPath;
use XML::XPath::XMLParser;

my $xp = XML::XPath->new(filename => 'test.xml');
my $nodeset = $xp->find('/states/state/*'); # find all subnodes

foreach my $node ($nodeset->get_nodelist) {
    print "FOUND: ", XML::XPath::XMLParser::as_string($node), "\n";
}

with this example XML file:

<?xml version="1.0"?>

<states>
<state xmlns="http://google.com" id="1">
  <randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id="2">
  <randomName2 type="boolean">1</randomName2>
</state>
</states>

This piece of code prints:

FOUND: <randomName1 type="boolean">0</randomName1>
FOUND: <randomName2 type="boolean">1</randomName2>

perl+cpan rocks!

深爱不及久伴 2024-10-15 06:46:57

通过将 g 前缀绑定到 http://google.com 命名空间 URI,您可以使用此表达式来选择 state 的任何元素子元素:

//g:state/*

< strong>注意:如果您知道架构不以 // 运算符开始路径,请使用完整路径。

更新:获取每个选定节点的字符串值不是XPath问题,而是宿主语言DOM方法问题。

With g prefix bound to http://google.com namespace URI, you could use this expression for selecting any element child of state:

//g:state/*

Note: If you know the schema don't start a path with // operator, use a full path.

Update: To get the string value of each of the selected nodes is not an XPath problem but host language DOM method problem.

独留℉清风醉 2024-10-15 06:46:57

感谢所有写回复的人,事实证明我只是一个白痴。在我调用子例程的方式中,它只是在每个其他集合上正确传递变量,因此 my $value = $element->string_value; 正在完成它的工作并仅返回 0,因为值为 1 的集合将被忽略。

我很抱歉浪费了任何人的时间……这不是我想给 stackoverflow 社区留下的第一印象,但再次感谢您的回复。

thanks to everyone that wrote a response, turns out i'm just a moron. in the way i was calling the sub-routine, it was only passing the variables properly on every other set so my $value = $element->string_value; was doing it's job and returning just 0 because the sets where the value was 1 were being passed over.

my apologies for wasting anyone's time...not the first impression I wanted to make to the stackoverflow community but thanks again for the responses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文