查询非常大的 xml 文件
Querying very large xml files
我有一个合并的非常大的 xml 文件,大小为 GB。我正在使用以下代码和 xpath 查询来读取和处理数据。
IColumn column = output.Schema.FirstOrDefault(col => col.Type != typeof(string));
if (column != null)
{
throw new ArgumentException(string.Format("Column '{0}' must be of type 'string', not '{1}'", column.Name, column.Type.Name));
}
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Auto;//.Fragment;
XmlReader r = XmlReader.Create(input.BaseStream, settings);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(r);
//xmlDocument.LoadXml("<root/>");
//xmlDocument.DocumentElement.CreateNavigator().AppendChild(r);
//xmlDocument.Load(input.BaseStream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
if (this.namespaces != null)
{
foreach (Match nsdef in xmlns.Matches(this.namespaces))
{
string prefix = nsdef.Groups[1].Value;
string uri = nsdef.Groups[3].Value;
nsmgr.AddNamespace(prefix, uri);
}
}
foreach (XmlNode xmlNode in xmlDocument.DocumentElement.SelectNodes(this.rowPath, nsmgr))
{
foreach (IColumn col in output.Schema)
{
var explicitColumnMapping = this.columnPaths.FirstOrDefault(columnPath => columnPath.Value == col.Name);
XmlNode xml = xmlNode.SelectSingleNode(explicitColumnMapping.Key ?? col.Name, nsmgr);
output.Set(explicitColumnMapping.Value ?? col.Name, xml == null ? null : xml.InnerXml);
}
yield return output.AsReadOnly();
}
但是,它只适用于 MB 规模的较小文件。它在本地工作正常但对 ADLA 失败。我也需要使用名称空间管理器。我如何缩放它以便我可以处理更大的文件。在提交带有大文件的作业时,我总是在没有任何信息的情况下收到此错误。
VertexFailedError
复制我在 MSDN 论坛中对同一个问题的回答:
U-SQL 默认情况下,提取器会横向扩展以在输入文件的较小部分(称为范围)上并行工作。这些扩展区的大小约为 250MB。
如果您正在处理的数据不适合某个范围,您必须使用 C# 属性告诉提取器,提取器必须查看整个文件。您可以通过在提取器之前添加以下部分来做到这一点 class:
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
在您的情况下,XML 文档显然不能拆分,因为解析器需要查看文档的开头和结尾。如果您只有一个 XML 文档,则尤其如此(旁注:在我看来,拥有单个 XML 文档或 JSON 文档的 GB 通常不是一个好主意)。
此外,我建议您查看我们在 GitHub 网站上提供的示例 XML 提取器:https://github.com/Azure/usql/tree/master/Examples/DataFormats
我有一个合并的非常大的 xml 文件,大小为 GB。我正在使用以下代码和 xpath 查询来读取和处理数据。
IColumn column = output.Schema.FirstOrDefault(col => col.Type != typeof(string));
if (column != null)
{
throw new ArgumentException(string.Format("Column '{0}' must be of type 'string', not '{1}'", column.Name, column.Type.Name));
}
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Auto;//.Fragment;
XmlReader r = XmlReader.Create(input.BaseStream, settings);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(r);
//xmlDocument.LoadXml("<root/>");
//xmlDocument.DocumentElement.CreateNavigator().AppendChild(r);
//xmlDocument.Load(input.BaseStream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
if (this.namespaces != null)
{
foreach (Match nsdef in xmlns.Matches(this.namespaces))
{
string prefix = nsdef.Groups[1].Value;
string uri = nsdef.Groups[3].Value;
nsmgr.AddNamespace(prefix, uri);
}
}
foreach (XmlNode xmlNode in xmlDocument.DocumentElement.SelectNodes(this.rowPath, nsmgr))
{
foreach (IColumn col in output.Schema)
{
var explicitColumnMapping = this.columnPaths.FirstOrDefault(columnPath => columnPath.Value == col.Name);
XmlNode xml = xmlNode.SelectSingleNode(explicitColumnMapping.Key ?? col.Name, nsmgr);
output.Set(explicitColumnMapping.Value ?? col.Name, xml == null ? null : xml.InnerXml);
}
yield return output.AsReadOnly();
}
但是,它只适用于 MB 规模的较小文件。它在本地工作正常但对 ADLA 失败。我也需要使用名称空间管理器。我如何缩放它以便我可以处理更大的文件。在提交带有大文件的作业时,我总是在没有任何信息的情况下收到此错误。
VertexFailedError
复制我在 MSDN 论坛中对同一个问题的回答:
U-SQL 默认情况下,提取器会横向扩展以在输入文件的较小部分(称为范围)上并行工作。这些扩展区的大小约为 250MB。
如果您正在处理的数据不适合某个范围,您必须使用 C# 属性告诉提取器,提取器必须查看整个文件。您可以通过在提取器之前添加以下部分来做到这一点 class:
[SqlUserDefinedExtractor(AtomicFileProcessing = true)]
在您的情况下,XML 文档显然不能拆分,因为解析器需要查看文档的开头和结尾。如果您只有一个 XML 文档,则尤其如此(旁注:在我看来,拥有单个 XML 文档或 JSON 文档的 GB 通常不是一个好主意)。
此外,我建议您查看我们在 GitHub 网站上提供的示例 XML 提取器:https://github.com/Azure/usql/tree/master/Examples/DataFormats