使用 F# XMLProvider 解析带有命名空间的 XML
Parsing an XML with namespaces using F# XMLProvider
我一直在尝试使用 XMLProvider 解析 XML NLog 消息。
在我的项目中,我按以下方式定义了提供者:
XmlProvider<"""
<log4j:event
logger="MyTest" level="INFO" timestamp="1597329370954" thread="1">
<log4j:message>
Running task
</log4j:message>
<log4j:locationInfo class="My.Task" method="Void main(System.String[])" />
<nlog:eventSequenceNumber>
11
</nlog:eventSequenceNumber>
<nlog:locationInfo assembly="My.Task, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<nlog:properties />
<log4j:properties>
<data name="log4japp" value="My.Task(64400)" />
<data name="log4jmachinename" value="BNT" />
</log4j:properties>
</log4j:event>""">
但这无法编译,因为我收到有关缺少命名空间定义的异常。
所以我将 xmlns 添加到根元素,使其成为:
XmlProvider<"""
<log4j:event
xmlns:log4j="http://jakarta.apache.org/log4j/"
xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd"
logger="MyTest" level="INFO" timestamp="1597329370954" thread="1">
<log4j:message>
...
...
</log4j:event>""">
它帮助我的项目编译,但它在尝试解析 XML:
时在运行时抛出异常
'log4j' is an undeclared prefix. Line 1, position 2.
我通过预处理 xml 并从所有标签中删除所有 xml 名称空间来解决这个问题。虽然这行得通,但我想知道是否有更好的解决方案。
这对我来说很好用,但您需要在示例 XML 和实际数据中都包含 XML 命名空间声明。例如,以下工作正常:
// Simplified declaration with namespaces included
type X = XmlProvider<"""
<log4j:event xmlns:log4j="http://jakarta.apache.org/log4j/"
xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd">
<log4j:message>Running task</log4j:message>
<nlog:eventSequenceNumber>11</nlog:eventSequenceNumber>
</log4j:event>""">
// Load a sample data file with namespaces included
let x = X.Parse("""
<log4j:event xmlns:log4j="http://jakarta.apache.org/log4j/"
xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd">
<log4j:message>Running task</log4j:message>
<nlog:eventSequenceNumber>11</nlog:eventSequenceNumber>
</log4j:event>""")
// Returns the data from the XML just fine!
x.Message
x.EventSequenceNumber
如果您从数据中省略 XML 命名空间声明,则会失败:
let y = X.Parse("""
<log4j:event>
<log4j:message>Running task</log4j:message>
<nlog:eventSequenceNumber>11</nlog:eventSequenceNumber>
</log4j:event>""")
我认为没有办法告诉 XML 类型提供者隐式包含命名空间声明 - 我可以看到这将是一个有用的功能,所以请随时提出建议项目 GitHub!
我一直在尝试使用 XMLProvider 解析 XML NLog 消息。 在我的项目中,我按以下方式定义了提供者:
XmlProvider<"""
<log4j:event
logger="MyTest" level="INFO" timestamp="1597329370954" thread="1">
<log4j:message>
Running task
</log4j:message>
<log4j:locationInfo class="My.Task" method="Void main(System.String[])" />
<nlog:eventSequenceNumber>
11
</nlog:eventSequenceNumber>
<nlog:locationInfo assembly="My.Task, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<nlog:properties />
<log4j:properties>
<data name="log4japp" value="My.Task(64400)" />
<data name="log4jmachinename" value="BNT" />
</log4j:properties>
</log4j:event>""">
但这无法编译,因为我收到有关缺少命名空间定义的异常。 所以我将 xmlns 添加到根元素,使其成为:
XmlProvider<"""
<log4j:event
xmlns:log4j="http://jakarta.apache.org/log4j/"
xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd"
logger="MyTest" level="INFO" timestamp="1597329370954" thread="1">
<log4j:message>
...
...
</log4j:event>""">
它帮助我的项目编译,但它在尝试解析 XML:
时在运行时抛出异常 'log4j' is an undeclared prefix. Line 1, position 2.
我通过预处理 xml 并从所有标签中删除所有 xml 名称空间来解决这个问题。虽然这行得通,但我想知道是否有更好的解决方案。
这对我来说很好用,但您需要在示例 XML 和实际数据中都包含 XML 命名空间声明。例如,以下工作正常:
// Simplified declaration with namespaces included
type X = XmlProvider<"""
<log4j:event xmlns:log4j="http://jakarta.apache.org/log4j/"
xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd">
<log4j:message>Running task</log4j:message>
<nlog:eventSequenceNumber>11</nlog:eventSequenceNumber>
</log4j:event>""">
// Load a sample data file with namespaces included
let x = X.Parse("""
<log4j:event xmlns:log4j="http://jakarta.apache.org/log4j/"
xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd">
<log4j:message>Running task</log4j:message>
<nlog:eventSequenceNumber>11</nlog:eventSequenceNumber>
</log4j:event>""")
// Returns the data from the XML just fine!
x.Message
x.EventSequenceNumber
如果您从数据中省略 XML 命名空间声明,则会失败:
let y = X.Parse("""
<log4j:event>
<log4j:message>Running task</log4j:message>
<nlog:eventSequenceNumber>11</nlog:eventSequenceNumber>
</log4j:event>""")
我认为没有办法告诉 XML 类型提供者隐式包含命名空间声明 - 我可以看到这将是一个有用的功能,所以请随时提出建议项目 GitHub!