【问题标题】:Broad thoughts on XML nodes to SQL through datatables?通过数据表对 XML 节点到 SQL 的广泛思考?
【发布时间】:2014-03-27 18:04:06
【问题描述】:

目前还不能更具体地说明这一点。我是 C# 新手,需要创建一个应用程序来恢复我们的部分数据库...

我有一系列独立的 XML 文件,它们跨越几个不同的文件夹。说 \FOLDER\P_0001\P_000002.xml 然后 \FOLDER\P_0002\P_000065.xml (初始文件夹始终相同,但 P_000X 文件夹的数量始终不同。那些是其中包含多个 XML 文件的文件夹。

这是需要读取的 XML 格式。

    <?xml version="1.0" encoding="utf-16"?>
<EXAMS>
  <EXAM id="15" majver="1" minver="1" width="1128" height="910">
    <NAME xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">Artefact reduced program</NAME>
    <PATIENT id="2" />
    <OBJECTS>
      <TAKE dbid="116" height="1280" width="2648">
        <VIEW majver="1" minver="2" maximized="0" x="0" y="122" width="1124" height="653" vx="199" vy="0" vWidth="2248" vHeight="1280" rotation="0" type="XP" regio="01" position="" orientation="" title="01XP 12.03.05: P1A, Ansicht Artefact reduced prog.." macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9259" yPelsPerMeter="9259" calibrated="0" calibrationFactor="1000">
          <PROPERTIES>
            <PROPERTY name="NGDevicePluginData" value="" />
            <PROPERTY name="NGPostProcessing" value="" />
            <PROPERTY name="NGDoseValues" value="" />
          </PROPERTIES>
          <DIAGNOSIS x="0" y="136" width="0" height="0" />
        </VIEW>
      </TAKE>
    </OBJECTS>
  </EXAM>
  <EXAM id="16" majver="1" minver="1" width="1128" height="910">
    <NAME xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">Ceph</NAME>
    <PATIENT id="2" />
    <OBJECTS>
      <TAKE dbid="120" height="2136" width="2808">
        <VIEW majver="1" minver="2" maximized="0" x="4" y="447" width="561" height="440" vx="2" vy="1" vWidth="2805" vHeight="2135" rotation="0" type="XC" regio="03" position="" orientation="" title="03XC 28.07.04: 30x23, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
          <PROPERTIES>
            <PROPERTY name="NGDevicePluginData" value="" />
            <PROPERTY name="NGPostProcessing" value="" />
            <PROPERTY name="NGDoseValues" value="" />
          </PROPERTIES>
          <DIAGNOSIS x="4" y="460" width="0" height="0" />
        </VIEW>
      </TAKE>
      <TAKE dbid="121" height="2136" width="1756">
        <VIEW majver="1" minver="2" maximized="0" x="598" y="450" width="351" height="440" vx="1" vy="1" vWidth="1755" vHeight="2135" rotation="0" type="XC" regio="04" position="" orientation="" title="04XC 23.08.05: -, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
          <PROPERTIES>
            <PROPERTY name="NGDevicePluginData" value="" />
            <PROPERTY name="NGPostProcessing" value="" />
            <PROPERTY name="NGDoseValues" value="" />
          </PROPERTIES>
          <DIAGNOSIS x="598" y="463" width="0" height="0" />
        </VIEW>
      </TAKE>
      <TAKE dbid="118" height="2136" width="1756">
        <VIEW majver="1" minver="2" maximized="0" x="1" y="2" width="351" height="440" vx="1" vy="1" vWidth="1755" vHeight="2135" rotation="0" type="XC" regio="01" position="" orientation="" title="01XC 02.09.04: -, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="-9" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
          <PROPERTIES>
            <PROPERTY name="NGDevicePluginData" value="" />
            <PROPERTY name="NGPostProcessing" value="" />
            <PROPERTY name="NGDoseValues" value="" />
          </PROPERTIES>
          <DIAGNOSIS x="1" y="15" width="0" height="0" />
        </VIEW>
      </TAKE>
      <TAKE dbid="119" height="2136" width="1800">
        <VIEW majver="1" minver="2" maximized="0" x="358" y="1" width="360" height="440" vx="0" vy="1" vWidth="1800" vHeight="2135" rotation="0" type="XC" regio="03" position="" orientation="" title="03XC 02.09.04: -, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
          <PROPERTIES>
            <PROPERTY name="NGDevicePluginData" value="" />
            <PROPERTY name="NGPostProcessing" value="" />
            <PROPERTY name="NGDoseValues" value="" />
          </PROPERTIES>
          <DIAGNOSIS x="358" y="14" width="0" height="0" />
        </VIEW>
      </TAKE>
    </OBJECTS>
  </EXAM>

需要做的是读取xml中的某些节点,然后将它们添加到SQL中的不同行中。问题是,名字不一样。比如说,XML中的“NAME”实际上是进入SQL中TGroupRaw表中的tGrpSName......

但我迷路了。我假设我将首先以这种方式将 XML 读入数据集。

string path = "C:\\PDATA\\P_0000\\P_000002.xml";
        DataSet ds = new DataSet();
        ds.ReadXml(path);

然后我需要找到一种方法将节点映射到不同的名称,然后插入 SQL。 在我完成并正常工作后,我可以找到一种方法来遍历所有单独的 xml 文件并对每个文件执行相同的操作。

但是我迷路了。在不同的事情上工作了大约一个月,但没有任何线索。 有人能给我一些建议让我开始吗?

顺便说一句,我真正需要从 XML 文件中获取的唯一内容是患者 ID、姓名和考试 ID。

【问题讨论】:

  • 首先,我会完全忽略 DataSet。那是一种陈旧的技术,会让你误入歧途。
  • 谢谢大家!这非常适合让我入门。我不确定我会使用哪种方法,但我现在肯定朝着正确的方向前进!

标签: c# sql sql-server xml


【解决方案1】:

从概念上讲,我认为您拥有大部分解决方案。 将 XML 文件读入 XML 文档:此对象将您的文件转换为“树”格式。

然后使用阅读器的各种功能遍历(迭代)生成的树。在此过程中,您可以跳过处理那些您不关心的节点并使用 SQL 更新您的数据库。

顺便说一句,您的 XML 示例(在问题中)格式不正确 - 它缺少结束的“EXAMS”标签;]

这里有一个代码 sn-p,它显示了您需要的要点:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.parse();
        }


        XmlDocument xmldoc = new XmlDocument();

        public void parse()
        {
            xmldoc.Load("c:\\yourfile.xml");//load your XML file

            //set your starting point
            XmlNodeList xNodelset = xmldoc.DocumentElement.SelectNodes("EXAM");

            // traverse the XML 
            foreach (XmlNode xNode in xNodelset)
            {
                //here's where all the work is done: you can go over nodes, get their value


                //get the exam id attribute:
                int examID = int.Parse(xNode.Attributes[0].Value);

                //and eventually push them to your DB using SQL.
            }
        }
    }


}

【讨论】:

  • 我会远离XmlDocument 而使用LINQ to XML。它更加灵活且易于使用。
  • 我发现 XmlDocument - 尽管非常冗长 - 比 LINQ 更直观。从其他语言进入 .Net 的程序员不一定想学习 lambda 表达式来解析 XML。
  • 首先,真正的程序员最好习惯 lambda 表达式——即使是 Java 也有。其次,我通常不需要使用 lambda 表达式来使用 LINQ to XML。
【解决方案2】:

选项 A:

使用 XDocument 将 xml 映射到一些基本的 DTO 对象。

Parent/Children Xml to DTO Object Model with LINQ

选项 B:

您可以将 xml 直接发送到存储过程。

这里有足够的示例来向您展示如何将 xml“分解”成行。

declare @doc xml

select @doc= '

<EXAMS>
    <EXAM id="15" majver="1" minver="1" width="1128" height="910">
        <NAME xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">Artefact reduced program</NAME>
        <PATIENT id="2" />
        <OBJECTS>
            <TAKE dbid="116" height="1280" width="2648">
                <VIEW majver="1" minver="2" maximized="0" x="0" y="122" width="1124" height="653" vx="199" vy="0" vWidth="2248" vHeight="1280" rotation="0" type="XP" regio="01" position="" orientation="" title="01XP 12.03.05: P1A, Ansicht Artefact reduced prog.." macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9259" yPelsPerMeter="9259" calibrated="0" calibrationFactor="1000">
                    <PROPERTIES>
                        <PROPERTY name="NGDevicePluginData" value="" />
                        <PROPERTY name="NGPostProcessing" value="" />
                        <PROPERTY name="NGDoseValues" value="" />
                    </PROPERTIES>
                    <DIAGNOSIS x="0" y="136" width="0" height="0" />
                </VIEW>
            </TAKE>
        </OBJECTS>
    </EXAM>
    <EXAM id="16" majver="1" minver="1" width="1128" height="910">
        <NAME xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">Ceph</NAME>
        <PATIENT id="2" />
        <OBJECTS>
            <TAKE dbid="120" height="2136" width="2808">
                <VIEW majver="1" minver="2" maximized="0" x="4" y="447" width="561" height="440" vx="2" vy="1" vWidth="2805" vHeight="2135" rotation="0" type="XC" regio="03" position="" orientation="" title="03XC 28.07.04: 30x23, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
                    <PROPERTIES>
                        <PROPERTY name="NGDevicePluginData" value="" />
                        <PROPERTY name="NGPostProcessing" value="" />
                        <PROPERTY name="NGDoseValues" value="" />
                    </PROPERTIES>
                    <DIAGNOSIS x="4" y="460" width="0" height="0" />
                </VIEW>
            </TAKE>
            <TAKE dbid="121" height="2136" width="1756">
                <VIEW majver="1" minver="2" maximized="0" x="598" y="450" width="351" height="440" vx="1" vy="1" vWidth="1755" vHeight="2135" rotation="0" type="XC" regio="04" position="" orientation="" title="04XC 23.08.05: -, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
                    <PROPERTIES>
                        <PROPERTY name="NGDevicePluginData" value="" />
                        <PROPERTY name="NGPostProcessing" value="" />
                        <PROPERTY name="NGDoseValues" value="" />
                    </PROPERTIES>
                    <DIAGNOSIS x="598" y="463" width="0" height="0" />
                </VIEW>
            </TAKE>
            <TAKE dbid="118" height="2136" width="1756">
                <VIEW majver="1" minver="2" maximized="0" x="1" y="2" width="351" height="440" vx="1" vy="1" vWidth="1755" vHeight="2135" rotation="0" type="XC" regio="01" position="" orientation="" title="01XC 02.09.04: -, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="-9" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
                    <PROPERTIES>
                        <PROPERTY name="NGDevicePluginData" value="" />
                        <PROPERTY name="NGPostProcessing" value="" />
                        <PROPERTY name="NGDoseValues" value="" />
                    </PROPERTIES>
                    <DIAGNOSIS x="1" y="15" width="0" height="0" />
                </VIEW>
            </TAKE>
            <TAKE dbid="119" height="2136" width="1800">
                <VIEW majver="1" minver="2" maximized="0" x="358" y="1" width="360" height="440" vx="0" vy="1" vWidth="1800" vHeight="2135" rotation="0" type="XC" regio="03" position="" orientation="" title="03XC 02.09.04: -, Ansicht Ceph" macroDbId="1" flippedHoriz="0" flippedVert="0" inverted="0" brightness="0" contrast="0" xPelsPerMeter="9615" yPelsPerMeter="9615" calibrated="0" calibrationFactor="1000">
                    <PROPERTIES>
                        <PROPERTY name="NGDevicePluginData" value="" />
                        <PROPERTY name="NGPostProcessing" value="" />
                        <PROPERTY name="NGDoseValues" value="" />
                    </PROPERTIES>
                    <DIAGNOSIS x="358" y="14" width="0" height="0" />
                </VIEW>
            </TAKE>
        </OBJECTS>
    </EXAM>
</EXAMS>
'

;WITH XMLNAMESPACES('urn:schemas-microsoft-com:datatypes' AS peanut)
SELECT 
      EXAM_ID =         Y.i.value('(../../../../../@id)[1]', 'varchar(40)')
    , DATATYPE_DT =     Y.i.value('(../../../../../NAME/@peanut:dt)[1]', 'varchar(40)')
    , PATIENT_ID =      Y.i.value('(../../../../../PATIENT/@id)[1]', 'varchar(40)')
    , PROPERTY_NAME =   Y.i.value('@name[1]', 'varchar(40)') 
    , PROPERTY_VALUE =  Y.i.value('@value[1]', 'varchar(40)') 
    , DIAGNOSIS_X =     Y.i.value('(../../DIAGNOSIS/@x)[1]', 'varchar(40)') 
FROM 
    @doc.nodes('/EXAMS/EXAM/OBJECTS/TAKE/VIEW/PROPERTIES/PROPERTY') AS Y(i)

【讨论】:

    猜你喜欢
    • 2019-08-15
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 2019-12-18
    相关资源
    最近更新 更多