- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我目前正在重写一个 PHP 类,该类试图将 XML 文件拆分成更小的 block ,以使用 XMLReader 和 XMLWriter 而不是当前的基本文件系统和正则表达式方法。
但是,我不知道如何从 XML 序言中获取版本、编码和独立标志。
我的测试 XML 文件的开头如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fakedoctype SYSTEM "fake_doc_type.dtd">
<!--
This is a comment, it's here to try and get the parser to break in some way
-->
<root attribute="value" otherattribute="othervalue">
我可以让读者打开它并使用 read()、next() 等浏览文档,但我似乎无法获得 <?xml ... ?>
中的任何内容。 .我能够访问的第一件事是伪造的 DOCTYPE。
我的测试代码如下:
$a = new XMLReader ();
var_dump ($a -> open ('/path/to/test/file.xml')) // true
var_dump ($a -> nodeType); // 0
var_dump ($a -> name); // ""
var_dump ($a -> readOuterXML ()); // ''
var_dump ($a -> read ()); // true
var_dump ($a -> nodeType); // 10
var_dump ($a -> readOuterXML ()); // <!DOCTYPE fakedoctype SYSTEM "fake_doc_type.dtd">
当然,我总是可以假设 XML 1.0,编码为 UTF8 和独立 = 是,但为了正确性,我真的更愿意能够获取我的源提要中的值并在生成拆分时使用它们文件。
关于 XMLReader 和 XMLwriter 的文档似乎很差,所以我很有可能错过了文档中的某些内容。有谁知道在这种情况下该怎么办?
最佳答案
我从 XMLReader
知道的,即使它有 XMLReader::XML_DECLARATION
常量,我在使用 XMLReader::read( )
在 XMLReader::$nodeType
属性中。
看起来它被跳过了,我也想知道为什么会这样,我还没有找到任何标志或选项来改变这种行为。
对于输出,XMLReader
总是返回 UTF-8 编码的字符串。这与 PHP 中其他基于 libxml 的部分相同。所以从那方面来说,一切都很清楚。但我认为这不是您感兴趣的部分,而是您使用 XMLReader::open()
打开的文件中输入的具体字符串。
不是专门针对 XMLReader
我曾经创建过 a utility class I named XMLRecoder
它能够根据 XML 声明和 BOM 检测 XML 字符串的编码。我认为你应该两者都做。这是我认为您仍然需要使用正则表达式的一部分,但因为 XML 声明必须是第一件事,而且它是一个处理指令 (PI),即 very well and strict defined。你应该可以看到里面的内容。
这是 XMLRecoder
代码中的一些相关部分:
### excerpt from https://gist.github.com/hakre/5194634
/**
* pcre pattern to access EncodingDecl, see <http://www.w3.org/TR/REC-xml/#sec-prolog-dtd>
*/
const DECL_PATTERN = '(^<\?xml\s+version\s*=\s*(["\'])(1\.\d+)\1\s+encoding\s*=\s*(["\'])(((?!\3).)*)\3)';
const DECL_ENC_GROUP = 4;
const ENC_PATTERN = '(^[A-Za-z][A-Za-z0-9._-]*$)';
...
($result = preg_match(self::DECL_PATTERN, $buffer, $matches, PREG_OFFSET_CAPTURE))
&& $result = $matches[self::DECL_ENC_GROUP];
如上图所示,它一直持续到编码,所以还不完整。但是,对于提取编码的需要(以及您需要的版本),它应该可以完成工作。我已针对大量(数千)随机 XML 文档运行此程序以进行测试。
另一部分是BOM检测:
### excerpt from https://gist.github.com/hakre/5194634
const BOM_UTF_8 = "\xEF\xBB\xBF";
const BOM_UTF_32LE = "\xFF\xFE\x00\x00";
const BOM_UTF_16LE = "\xFF\xFE";
const BOM_UTF_32BE = "\x00\x00\xFE\xFF";
const BOM_UTF_16BE = "\xFE\xFF";
...
/**
* @param string $string string (recommended length 4 characters/octets)
* @param string $default (optional) if none detected what to return
* @return string Encoding, if it can not be detected defaults $default (NULL)
* @throws InvalidArgumentException
*/
public function detectEncodingViaBom($string, $default = NULL)
{
$len = strlen($string);
if ($len > 4) {
$string = substr($string, 0, 4);
} elseif ($len < 4) {
throw new InvalidArgumentException(sprintf("Need at least four characters, %d given.", $len));
}
switch (true) {
case $string === self::BOM_UTF_16BE . $string[2] . $string[3]:
return "UTF-16BE";
case $string === self::BOM_UTF_8 . $string[3]:
return "UTF-8";
case $string === self::BOM_UTF_32LE:
return "UTF-32LE";
case $string === self::BOM_UTF_16LE . $string[2] . $string[3]:
return "UTF-16LE";
case $string === self::BOM_UTF_32BE:
return "UTF-32BE";
}
return $default;
}
对于 BOM 检测,我也确实针对同一组 XML 文档运行了它,但是,使用 BOM 的并不多。如您所见,检测顺序针对更常见的场景进行了优化,同时处理了不同 BOM 之间的重复二进制模式。我遇到的大多数文档都没有 BOM,您主要需要它来确定文档是否为 UTF-32 编码。
希望这至少能提供一些见解。
关于PHP XMLReader,获取版本和编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15477999/
我想将使用 .Net Compact Framework 3.5 制作的 Windows Mobile 应用程序降级到 .Net Compact Framework 2.0 SP2。 但是...我不知
我正在尝试从 xml 字符串中读取但是, ` XmlReader reader=XmlReader.Create(new StringReader(stringXml)` 读者总是没有。为什么没有
在以下代码段中,当我遇到一个元素时,使用 XmlReader。我想按原样阅读它,包括元素中的所有属性和命名空间装饰。使用 oXml.Name 属性,我只能获取标签名称。是否有获取标签本身的功能? oX
这可能是一个关于 XmlReader 的幼稚问题,但我还没有在 MSDN 文档中找到答案。 假设我有 XSD SchemaTest.xsd
我想做这样的事情: stringBuilder.AppendLine(" globalVar." + reader.GetAttribute(i).Name + " = " + reader[i]
使用 XMLReader 方法解析 XML 文件时,如何获取元素的父节点? $xml = new XMLReader(); $xml->XML($xmlString); while($xml->rea
这很奇怪。我有一个 WCF Message我正在尝试将正文的内容读入 XmlDocument。消息正文的内容在网络上看起来像这样(在打开 WCF 跟踪的情况下进行检查): (GMT-05:0
我有一个 Xml 文档,其中一些元素如下所示: W X Y Z ABC 我的目标是从上面的例子中得到“ABC”。我尝试查看 XmlElement 类中的 InnerText(返回“WXYZABC”
我有以下代码: for (i = 1; i <= loopsNeeded; i++) { lblCurrent.Text = string.Format("{0} of
我正在尝试将 xml 加载到 XDocument 对象中。 public void ValidateRules(XmlReader xml) { xml.MoveToContent();
我必须为我的商店解析 3 个远程 XML 文件(产品、价格、类别),其中最大的大约有 500MB+。我必须解析它们并插入到 mysql 数据库中。 我可以从两种格式中选择 所有 3 个 XML 文件压
我正在尝试使用 XMLReader ( https://github.com/amarcadet/XMLReader ) 在 objective-c 中制作一个将解析 xml 文档的应用程序:
代码如下: string str = "AppleMango"; using (XmlReader xmlReader = XmlReader.Create(new StringReader(str)
我了解我们如何使用如下代码示例.. public class Sample { public static void Main() { using (XmlReader
我正在使用 XmlReader 读取非常大的 XML 文件(超过 6GB 的数据)以加快一切速度并且工作得非常好。 我在另一个线程中执行此操作(不使用后台工作程序)并且我不知道如何更新进度条,因为 X
关注此introduction可以通过导入命名空间 System.Xml 来使用 XMLReader 类。在我的 Visual Studio 项目中,我使用 .NET 4.0,但 System.Xml
我正在使用以下代码使用 XmlReader 读取一些 XML: XmlReaderSettings settings = new XmlReaderSettings(); settings.Valid
好的,所以我有这个 XML 文件: Iron Repeater true 19 19 50 18 1 1 5 39
为什么我应该将 XMLReader 与 SAXParser 一起使用?我经常看到这种用法: sp = spf.newSAXParser(); XMLReader xr
我有这个 xml 文件。 8.582207 3 true
我是一名优秀的程序员,十分优秀!