简体   繁体   English

将API中的XML数据解析/反序列化为对象-XML文档中存在错误(1871,60)

[英]Parsing/Deserialize XML data from API into object - There is an error in XML document (1871, 60)

I am working with an XML api, which returns the following: 我正在使用XML api,该API返回以下内容:

<inventory>
    <product inventoryId="1722474"  externalReference="SM" site="global" total="0" allocated="0" available="0" frozen="0" onOrder="0" lastStockChangeId="505401" lastLineRequirementChangeId="0"/>
    <product inventoryId="1722476"  externalReference="PM" site="global" total="0" allocated="0" available="0" frozen="0" onOrder="0" lastStockChangeId="243256" lastLineRequirementChangeId="0"/>
    .... 1000s of nodes ....
</inventory>

So, from this returned xml nodes, I am only interested in the following fields/attributes externalReference and available . 因此,从这个返回的xml节点中,我仅对以下字段/属性externalReferenceavailable感兴趣。

Therefore; 因此; I created the following class to describe the xml content I am going to deserialize/parse: 我创建了以下类来描述我要反序列化/解析的xml内容:

[XmlRoot(ElementName = "product")]
public class StockLevelProduct
{
    [XmlAttribute(AttributeName = "externalReference")]
    public string ExternalReference { get; set; }

    [XmlAttribute(AttributeName = "available")]
    public string Available { get; set; }
}

[XmlRoot(ElementName = "inventory")]
public class StockLevelResult
{
    [XmlElement(ElementName = "product")]
    public List<StockLevelProduct> Product { get; set; }
}

Then I put it all together like this: 然后,我将所有内容整理成这样:

// Init
StockLevelResult stockLevelResult;

// Anticipate errors
try
{
    // Generate request url
    string requestUrl = string.Format("{0}/remotewarehouse/inventory.xml?channel={1}",
        apiUrl,
        apiChannel);

    // Call api
    string apiResultXmlString = ApiGet(requestUrl);

    // Fix api result xml string
    if (!apiResultXmlString.Contains("<?xml"))
        apiResultXmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + apiResultXmlString;

    // Deserialize xml string to object
    stockLevelResult = XmlParser.Parse<StockLevelResult>(apiResultXmlString);
}
catch (Exception ex)
{
    Console.WriteLine("Failed to download stock levels - " + ex.Message);
}

Note* the returned xml string from the API server does not contain <?xml version="1.0" encoding="UTF-8"?> so I manually add it. 注意*从API服务器返回的xml字符串不包含<?xml version="1.0" encoding="UTF-8"?>因此我手动添加了它。 Note sure if XmlParser.Parse requires it. 请注意是否XmlParser.Parse需要它。

When this code executes; 该代码何时执行; I get the following exception being thrown: 我收到以下异常:

There is an error in XML document (1871, 60) XML文档中有错误(1871,60)

Any ideas why this isn't working? 任何想法为什么这不起作用? Is it an issue with the returned XML string? 返回的XML字符串有问题吗? or the way I am trying to parse/deserialize it? 还是我尝试解析/反序列化的方式?

Try this 尝试这个

XmlSerializer xs = new XmlSerializer(typeof(StockLevelResult));
StringReader sReader = new StringReader(apiResultXmlString);
XmlTextReader reader = new XmlTextReader(sReader);
stockLevelResult = (StockLevelResult)xs.Deserialize(reader);

The exception was caused by bad data in the api XML response: 异常是由api XML响应中的错误数据引起的:

<product inventoryId="1726460" externalReference="V02002B&R" site="global" total="0" allocated="0" available="0" frozen="0" onOrder="0" lastStockChangeId="76231" lastLineRequirementChangeId="0"/>

ie & in this attribute externalReference="V02002B&R" &在此属性externalReference="V02002B&R"

I fixed it thanks to this answer like this: 我通过以下答案修复了该问题

// Call api
string apiResultXmlString = ApiGet(requestUrl);

// Fix api result xml string
if (!apiResultXmlString.Contains("<?xml"))
    apiResultXmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + apiResultXmlString;

// Fix bad response data
string pattern = "(?<start>>)(?<content>.+?(?<!>))(?<end><)|(?<start>\")(?<content>.+?)(?<end>\")";
apiResultXmlString = System.Text.RegularExpressions.Regex.Replace(apiResultXmlString, pattern, m =>
            m.Groups["start"].Value +
            System.Web.HttpUtility.HtmlEncode(System.Web.HttpUtility.HtmlDecode(m.Groups["content"].Value)) +
            m.Groups["end"].Value);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM