问候,
我的目标:要验证XML文档,请将数据加载到自定义对象中。我正在使用Linq to XML。
我的情况:我正在努力使用命名空间和/或Linq语法。我以为一切都在运作。代码读取XML并加载对象,但实现了XDocument.Validate传递了所有内容而没有真正验证。我想那是松懈的验证。为了使XDocument.Validate()方法有效,我在XML文件中添加了一个Namespace。验证工作正常,但现在我的Linq查询创建的XElement在尝试访问.Element(“Field”)时返回null。值。
我的问题:
当我尝试在Linq查询中指定特定元素时,我从未得到结果。它 只有在
时才有效IEnumerable<XElement> residents =
from xeRes in xD.Elements()
select xeRes;
但
IEnumerable<XElement> residents =
from xeRes in xD.Elements("Resident")
select xeRes;
什么都不返回。
欢迎任何建议。
谢谢,
Code Snipets:
XSD
<?xml version="1.0" encoding="utf-8"?> <xsd:schema xmlns="http://kinduit.net/ResidentNS" xmlns:schema="http://kinduit.net/ResidentNS" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified"><xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="Resident">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FacilityID">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="ResidentID" maxOccurs="unbounded">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="20" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="ResidentID2" maxOccurs="unbounded">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="20" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>...
XML
<?xml version="1.0"?><Resident xmlns="http://kinduit.net/ResidentNS">
<FacilityID>WARMSPRINGS</FacilityID>
<ResidentID>WS585459</ResidentID>
<ResidentID2>145214</ResidentID2>...
C#
// Validate XML Schema...
XmlSchemaSet sc = new XmlSchemaSet();
XNamespace xNs = "http://kinduit.net/ResidentNS";
try
{
// Validate against the XSD...
string location = System.Reflection.Assembly.GetAssembly(typeof(ElementsBC.Interface)).Location;
sc.Add(xNs.ToString(), location.Replace("ElementsBC.dll", "") + "\\InterfaceXSD\\resident.xsd");
XDocument xD = this.ConvertToXDocument(ResidentXML);
xD.Validate(sc, (sender, e) => { throw new Exception(e.Message); }, true);
IEnumerable<XElement> residents =
from xeRes in xD.Elements()
select xeRes;
counts[0] = residents.Count();
foreach (XElement el in residents)
{
try
{
// get facility...
string facilityid = el.Element("FacilityID").Value.ToString();
如果XML中有名称空间,则最后一行返回null。如果没有命名空间,则此代码运行不严格的验证,但可以读取值。
建议?
答案 0 :(得分:1)
您需要在调用中包含命名空间。
XNamespace ns = xD.GetDefaultNamespace() // Or some other way of getting the namespace you want.
IEnumerable<XElement> residents = from xeRes in xD.Elements(ns + "Resident")
select xeRes;
答案 1 :(得分:1)
感谢Tim Jarvis和Broken Glass。我通过结合他们的回答找到答案。我在上面的代码中遇到了三个问题。
请参阅下面的更正代码。
<强> XSD 强>
<?xml version="1.0" encoding="utf-8"?><xsd:schema xmlns:xs="http://kinduit.net/ResidentNS" targetNamespace="http://kinduit.net/ResidentNS" xmlns="http://kinduit.net/ResidentNS" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="Resident">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FacilityID">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="ResidentID" maxOccurs="unbounded">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="20" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="ResidentID2" maxOccurs="unbounded">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="20" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>...
XML :无变化
<强> C#强>
// Validate XML Schema...
XmlSchemaSet sc = new XmlSchemaSet();
XNamespace xNs = "http://kinduit.net/ResidentNS";
try
{
// Validate against the XSD...
string location = System.Reflection.Assembly.GetAssembly(typeof(ElementsBC.Interface)).Location;
sc.Add(xNs.ToString(), location.Replace("ElementsBC.dll", "") + "\\InterfaceXSD\\resident.xsd");
XDocument xD = this.ConvertToXDocument(ResidentXML);
xD.Validate(sc, (sender, e) => { throw new Exception(e.Message); }, true);
IEnumerable<XElement> residents =
from xeRes in xD.Elements(xNs + "Resident")
select xeRes;
counts[0] = residents.Count();
foreach (XElement el in residents)
{
try
{
// get facility...
string facilityid = el.Element(xNs + "FacilityID").Value.ToString();
谢谢!
答案 2 :(得分:0)
您必须声明并使用命名空间:
XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
此外,您的XML中没有Resident
元素 - 有些名为element
的元素具有以“Resident”开头的属性name
。这些元素不是根节点的直接子节点,因此您必须在查询中使用Descendands()
而不是Elements()
。
说过这对我有用(返回3个节点):
XDocument xD = XDocument.Load("test.xml");
XNamespace xsd = "http://www.w3.org/2001/XMLSchema";
IEnumerable<XElement> residents = from xeRes in xD.Descendants(xsd + "element")
where xeRes.Attribute("name") != null
&& xeRes.Attribute("name").Value.StartsWith("Resident")
select xeRes;