4

我正在寻找一种 HTML 或 XML 解析器,它可以让人们访问输入字符串或文件中当前元素的偏移量/位置。

例如,如果遍历此字符串:

<div>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
    <p>sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>

我正在寻找一种方法来获取每个<p>标签的起始位置(包括空格),在这里:772.

如果 PHP 解析器本身支持它会很棒(我查看了DOMXMLReader和其他库在这个 SO 问题中提到但还没有找到方法),但否则任何语言/框架都是美好的。

注意:与此问题相关,但本地化程度较低。

4

2 回答 2

6

也许您可以使用通用 XML 解析器类(也在github 上)。
根据作者的描述:

  • 解析任意 XML 输入并构建一个包含所有标签和数据元素结构的数组。
  • 它只需一次调用即可验证和提取整个 XML 文档中的数据。它支持验证常见的标签值数据类型,并且可以使用子类执行自定义验证。
  • 可选地,跟踪每个元素的位置,以允许确定可能在上下文中出错的元素的确切位置。
  • 支持解析后的文件缓存,最大限度地减少重复解析同一个文件的开销。
  • 忽略标签属性的简化 XML (SML) 格式的优化解析。
  • 使用单个函数调用验证和提取整个 XML 文档中的数据

我已经使用以下代码对其进行了测试:

<?php

require('xml_parser.php');

$file_name = 'test.xml';
$error = XMLParseFile($parser, $file_name, 1, $file_name.'.cache');

foreach ($parser->structure as $key => $val) {
    if (is_array($val) && isset($val['Tag']) && !strcasecmp($val['Tag'], 'p')) {
        print_r($parser->positions[$key]);
    }
}

?>

test.xml文件包含您的示例 HTML 片段。
通过从命令行运行脚本,我得到以下输出:

Array
(
    [Line] => 2
    [Column] => 7
    [Byte] => 12
)
Array
(
    [Line] => 3
    [Column] => 7
    [Byte] => 80
)

因此,该Byte字段可能是您正在寻找的。
为了更好地理解它的工作原理,还请查看它的源代码

于 2013-01-23T21:33:15.177 回答
0

如果你不介意用 Java 编码(在 Java 编码之后,PHP 有一个解决方案),你可以indexOf在类中使用方法,String如果有这个标记则获取偏移量。

这是一个例子:

class Index {
    public static void main ( String [] args )
    {   
        String token = "<p>";
        String input = "<p> hola </p> <p> adios </a>";
        int beginIdx = -1; 
        while ( (beginIdx = input.indexOf( token, beginIdx + 1 )) != -1 ) {                                                                                                                                         
            System.out.println( "Token at: " + beginIdx );
        }   
    }   
}

输出是:

Token at: 0
Token at: 14

在 PHP 中有一个类似的函数:

int strrpos ( string $haystack , string $needle [, int $offset = 0 ] )

您可以快速查看有关它的“man”页面(它有一些示例): http: //php.net/manual/es/function.strrpos.php

于 2013-01-23T11:52:18.613 回答