【问题标题】:Forcing prefix on all xml elements in xml document在 xml 文档中的所有 xml 元素上强制使用前缀
【发布时间】:2015-10-27 11:29:22
【问题描述】:

我已经检查并尝试了多种解决此问题的方法,但仍然无法正常工作。

我从数据集(从 Excel 文件填充)创建一个 XML 文件。该文件工作正常,我已针对 XSD 对其进行了验证。我剩下的唯一问题是我在根元素中定义的命名空间前缀没有出现在 XMLDocument 中的任何元素中。以下是生成 XMLDocument 的代码(注意 - partDS 是从中加载 XML 文件的数据集):

Private Sub WriteXML_Click(sender As Object, e As EventArgs) Handles Writer.Click
    Dim fName As String = "C:\Users\ThisUser\Desktop\Plain.xml"

    partDS.DataSetName = "XMLDataDelivery"
    partDS.WriteXml(fName)

    Dim xDoc As New XmlDocument

    Dim schemaLocation As XmlAttribute = Nothing
    Dim schemaString As String = "http://www.w3.org/2001/XMLSchema-instance"
    Dim schemaValue As String = "http://www.tgin.org/trident/7143706-001 7143706-001RevA.xsd"

    Dim namespaceAttribute As XmlAttribute = Nothing
    Dim nsString As String = "http://www.w3.org/2000/xmlns/"
    Dim nsValue As String = "http://www.tgin.org/trident/7143706-001"

    Dim commonTimeElement As XmlElement = Nothing
    Dim commonTimeAttribute As XmlAttribute = Nothing
    Dim commonTimeString As String = "/XMLDataDelivery/CommonHeader/SubmittedDateTimeUTC"

    Dim dataTimeElement As XmlElement = Nothing
    Dim dataTimeAttribute As XmlAttribute = Nothing
    Dim dataTimeString As String = "/XMLDataDelivery/Data/LogisticsEvent/DateTime"

    Dim timeAttributeString = "dl:DateTime12HourWithoutFeb29"

    Dim dateTimeNodeList As XmlNodeList = Nothing
    Dim parentLevels As XmlNodeList = xDoc.SelectNodes("/XMLDataDelivery/Data/LogisticsEvent")
    Dim higherLevels As XmlNodeList = xDoc.SelectNodes("/XMLDataDelivery/Data/LogisticsEvent/Activity")
    Dim partLevels As XmlNodeList = xDoc.SelectNodes("/XMLDataDelivery/Data/LogisticsEvent/AssemblyItem")

    xDoc.Load(fName)

    'define XML namespace and attributes in XML header
    namespaceAttribute = xDoc.CreateAttribute("xmlns", "dl", nsString)
    namespaceAttribute.Value = nsValue
    xDoc.DocumentElement.Attributes.Append(namespaceAttribute)

    schemaLocation = xDoc.CreateAttribute("xsi", "schemaLocation", schemaString)
    schemaLocation.Value = schemaValue
    xDoc.DocumentElement.SetAttributeNode(schemaLocation)

    'define and set attributes for the dateTime elements in the XML
    commonTimeElement = xDoc.SelectSingleNode(commonTimeString)
    commonTimeAttribute = xDoc.CreateAttribute("xsi", "type", schemaString)
    commonTimeAttribute.Value = timeAttributeString
    commonTimeElement.SetAttributeNode(commonTimeAttribute)

    dataTimeAttribute = xDoc.CreateAttribute("xsi", "type", schemaString)
    dataTimeAttribute.Value = timeAttributeString

    Dim i As Integer = 0
    Do Until i > parentLevels.Count - 1
        parentLevels.ItemOf(i).InsertBefore(partLevels.ItemOf(i), higherLevels.ItemOf(i))
        i += 1
    Loop

    dateTimeNodeList = xDoc.SelectNodes("/XMLDataDelivery/Data/LogisticsEvent/DateTime")
    For Each item As XmlElement In dateTimeNodeList
        item.SetAttribute("type", schemaString, timeAttributeString)
    Next

    xDoc.Save(fName)

End Sub

生成类似于下面的 XML:

<XMLDataDelivery xmlns:dl="http://www.tgin.org/trident/7143706-001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tgin.org/trident/7143706-001 7143706-001RevA.xsd">
  <Data>
    <Location>Site01</Location>
    <LogisticsEvent>
      <DateTime>01-JUL-2015 12:00:00 PM</DateTime>
      <AssemblyItem>
        <ProductName>Test Part1</ProductName>
        <ProductNumber>998741</ProductNumber>
        <ProductDash>050</ProductDash>
        <SerialNumber>LX2247</SerialNumber>
        <ProductRevision>R</ProductRevision>
      </AssemblyItem>
      <Activity>Stat Change</Activity>
      <Condition>Good</Condition>
      <Usage>Production</Usage>
    <LogisticsEvent>
  </Data>
</XMLDataDelivery>

现在从我的研究中记得(在 vb.net 中编程 XML 仍然是新手),如果命名空间是在根目录中定义的,那么相同命名空间的前缀不需要(或不会?)出现在 XMLDocument 中的每个节点上。

虽然我同意这一点(并且我的验证者同意这是一个有效的 XML 文件),但如果没有将前缀附加到每个节点,将上传这些文件的系统将无法通过验证。

我尝试了多种修复方法,从简单地定义根前缀 (xDoc.DocumentElement.prefix = "dl") 到尝试不同的属性设置,使用命名空间管理器,但仍然没有任何东西可以坚持。

XML 文件是从头开始创建的(不是从任何模板加载的)。我确实尝试了命令 xDoc.GetNamespaceOfPrefix("dl") 但没有返回任何内容。

抱歉,这很长,但只是想确保我有足够的信息。感谢任何对此进行评论的人。

【问题讨论】:

  • 元素创建后不能更改namespace。您需要使用 proper namespace 重新创建元素
  • 在将数据集写入 XML partds.Namespace = "http://www.tgin...etc" partds.prefix = "dl" 之前,我将命名空间和前缀添加到数据集。前缀出现在根元素上,命名空间出现在父节点(CommonHeader、DataHeader 和数据)上,但是前缀不会出现在根元素以外的任何元素上。此外,在加载 xml 文档后,我尝试了命令 xdoc.GetNamespaceofPrefix("dl"),但它仍然没有返回任何内容。我觉得我在这里错过了一些基本的东西......
  • 我为 partds 数据集中的每个表添加了“dl”前缀。现在前缀显示在所有父节点上,命名空间xmlns="http://www.tgin.org/trident/7143706-001" 出现在所有子节点上。我想我快到了……?

标签: xml vb.net


【解决方案1】:

直到我进一步深入研究之前,我才意识到 Sam Ax 的意思(如果可以的话,我会支持你的评论)。最后,我没有意识到我可以将数据集中的数据列的前缀更改为与根中声明的命名空间相关联:

    partDS.Tables("CommonHeader").Prefix = "dl"
    partDS.Tables("DataHeader").Prefix = "dl"
    partDS.Tables("Data").Prefix = "dl"
    partDS.Tables("LogisticsEvent").Prefix = "dl"
    partDS.Tables("AssemblyItem").Prefix = "dl"

    Dim logCol As Integer = 0
    Dim assyCol As Integer = 0

    Do Until logCol > partDS.Tables("LogisticsEvent").Columns.Count - 1
        partDS.Tables("LogisticsEvent").Columns(logCol).Prefix = "dl"
        logCol += 1
    Loop

    Do Until assyCol > partDS.Tables("AssemblyItem").Columns.Count - 1
        partDS.Tables("AssemblyItem").Columns(assyCol).Prefix = "dl"
        assyCol += 1
    Loop

    partDS.DataSetName = "XMLDataDelivery"
    partDS.Namespace = "http://www.tgin.org/trident/7143706-001"
    partDS.Prefix = "dl"

非常感谢您的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多