首页 > 解决方案 > 无法使用 libtidy 获取 HTML 文本

问题描述

每个人 - 长期倾听者,第一次来电者。

我一直在 macOS 10.13 上使用 C 语言中的 libtidy。我从这里的示例代码开始,并将其修改为读取本地 html 文件,而不是使用 curl。除了文本之外,一切似乎都正常。它会在我的测试文件中找到并输出每个标签,但似乎根本无法获取文本,这让我发疯了。

有问题的代码出现在DumpNodetree-walking 函数中。我的破解版:

#include <stdio.h>
#include <tidy.h>
#include <tidybuffio.h>

/* Wrapper functions for file i/o */
int w_getc(void* ptr)
{
  return getc((FILE *)ptr);
}
void w_ungetc(void *ptr, unsigned char bv)
{
  ungetc((int)bv, (FILE *)ptr);
}
Bool w_feof(void *ptr)
{
  return (Bool)feof((FILE *)ptr);
}

/* Traverse the document tree */
void dumpNode(TidyDoc doc, TidyNode tnod, int indent)
{
  TidyNode child;
  for(child = tidyGetChild(tnod); child; child = tidyGetNext(child) ) {
    ctmbstr name = tidyNodeGetName(child);
    if (!name) {
      /* if it doesn't have a name, then it's probably text, cdata, etc... */
      TidyBuffer buf;
      tidyBufInit(&buf);
      if (tidyNodeHasText(doc, child) && tidyNodeGetText(doc, child, &buf)) {
        printf("%u, %u, %u\n", buf.size, buf.allocated, buf.next);
        printf("%*.*s\n", indent, indent, (buf.bp && buf.size > 0)?(char *)buf.bp:"");
      }
      tidyBufFree(&buf);
    }
    dumpNode(doc, child, indent + 4); /* recursive */
  }
}

int main(int argc, char **argv)
{
  if(argc == 2) {
    TidyDoc tdoc;
    int err;
    FILE *fp;
    TidyInputSource insrc;

    tdoc = tidyCreate();

    fp = fopen(argv[1], "r");
    if (!fp) return -1;
    
    if (tidyInitSource(&insrc, fp, &w_getc, &w_ungetc, &w_feof)) {
      err = tidyParseSource(tdoc, &insrc); /* parse the input */
      if(err >= 0) dumpNode(tdoc, tidyGetRoot(tdoc), 0); /* walk the tree */      
    }

    /* clean-up */
    fclose(fp);
    tidyRelease(tdoc);
    return err;

  }
  return 0;
}

还有我的编译器字符串:gcc -o TidyExample tidyexample.c -ltidy -DENABLE_DEBUG_LOG -DDEBUG_PPRINT -DDEBUG_INDENT

以下是我到目前为止的推断:

我没主意了。要么我做错了(可能),要么 libtidy 中有一个很大的错误(不太可能,但可能)。

ETA:这是一个很小的 ​​HTML 文件,当您调用TidyExample minimal.html结果时通常会出现空缓冲区:

<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<p>This is text.</p>
</body>
</html>

标签: ctidy

解决方案


好的,我找到了某种“解决方案”。它完成了工作,但我不知道为什么。

因此,在发现 之后-ltidys,我正在尝试设置漂亮的打印回调,我发现如果我设置了一个,输出将是我所期望的......即使我实际上没有设置回调!

说真的,我所要做的就是插入 line tidySetPrettyPrinterCallback(tdoc, NULL);,缓冲区填满并按应有的方式打印。注释掉它,它就会停止工作。

我研究了一些与 链接的其他功能,libtidys.a它们似乎具有相同的效果。不过,我还没有做过任何严格的实验。

如果有人对可能导致这种情况的原因有任何见解,为了我自己的知识,我很想知道。但我不打算进一步探究。由于我已经找到了解决问题的实用方法,所以我暂时先解决这个问题,然后着手处理我尝试使用 Tidy 的实际项目。


推荐阅读