我一直在使用示例XMLExtractor(从https://github.com/Azure/usql/tree/master/Examples/DataFormats克隆)从我的xml元素中提取属性 .
如果根元素具有任何已定义的属性,则提取器将无法工作 .
例如,我需要从以下XML文件中获取“rec”元素的“sTime”属性:
<lics xmlns="***" lVer="*" pID="*" aKey="*" cTime="*" gDel="*" country="*" fStr="*">
<rec Ver="*" hID="*.*.*" cSID="Y5/*=" uID="*\Rad.*" uSID="*/*=" cAttrs="*" sTime="*" eTime="*" projID="*" docID="*" imsID="*">
</rec>
</lics>
使用以下U-SQL脚本:
@e = EXTRACT a string, b string
FROM @"D:\file.xml"
USING new Microsoft.Analytics.Samples.Formats.Xml.XmlDomExtractor(rowPath:"rec",
columnPaths:new SQL.MAP<string, string> { {"@sTime", "a"} });
OUTPUT @e TO "D:/output.csv" USING Outputters.Csv(quoting:false);
这会写一个空文件 . 但是,如果我删除“lics”标签的属性,它的工作原理 .
<lics>
<rec Ver="*" hID="*.*.*" cSID="Y5/*=" uID="*\Rad.*" uSID="*/*=" cAttrs="*" sTime="*" eTime="*" projID="*" docID="*" imsID="*">
</rec>
</lics>
这是提取器的问题吗?或者是否需要在提取器的任何参数中定义?
2 回答
问题是
Microsoft.Analytics.Samples.Formats.Xml.XmlDomExtractor
完全忽略了XML命名空间 .更好的实现看起来像这样(虽然未经测试):
并像这样使用:
namespaces参数将被解析为namespace-prefix和namespace-uri部分,然后将用于驱动XPath查询 . 为方便起见,它支持以下任何值格式:
'xmlns:foo="http://uri/1" xmlns:bar="http://uri/2"'
"xmlns:foo='http://uri/1' xmlns:bar='http://uri/2'"
"xmlns:foo=http://uri/1 xmlns:bar=http://uri/2"
"foo=http://uri/1 bar=http://uri/2"
所以它可以直接从XML源复制它们,也可以手动创建它们而不用太大惊小怪 .
由于您使用的XML文档具有默认命名空间,并且XPath要求在表达式中使用您需要的任何命名空间的前缀,因此必须为命名空间URI选择命名空间前缀 . 我选择使用上面的
lics
.FWIW,解析名称空间参数的正则表达式分解如下:
我可能会使用另一个SQL.MAP来定义命名空间映射的前缀(并且不需要与文档中相同的前缀) .
我在这里创建了一个功能请求:https://feedback.azure.com/forums/327234-data-lake/suggestions/11675604-add-xml-namespace-support-to-xml-extractor . 请添加您的投票 .
UPDATE: The XmlDomExtractor now supports XML Namespaces. Use the following USING clause: