Je travaille sur un bug mystérieux dans le très bon projet open source Excel Data Reader. Il ignore les valeurs lues à partir de ma feuille de calcul OpenXML .xlsx particulière.Correction de problèmes XmlReader en utilisant ReadToDescendant et/ou ReadElementContentAsObject
Le problème se produit dans le ReadSheetRow method (code de démonstration ci-dessous). Le code source XML est enregistré par Excel et ne contient aucun espace qui correspond au comportement étrange. Toutefois, le format XML qui a été reformaté avec des espaces (par exemple, dans Visual Studio, accédez à Edition, Avancé, Format Document) fonctionne parfaitement!
données de test avec des espaces:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<sheetData>
<row r="5" spans="1:73" s="7" customFormat="1">
<c r="B5" s="12">
<v>39844</v>
</c>
<c r="C5" s="8"/>
<c r="D5" s="8"/>
<c r="E5" s="8"/>
<c r="F5" s="8"/>
<c r="G5" s="8"/>
<c r="H5" s="12">
<v>39872</v>
</c>
<c r="I5" s="8"/>
<c r="J5" s="8"/>
<c r="K5" s="8"/>
<c r="L5" s="8"/>
<c r="M5" s="8"/>
<c r="N5" s="12">
<v>39903</v>
</c>
</row>
</sheetData>
</worksheet>
données de test sans espace:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheetData><row r="5" spans="1:73" s="7" customFormat="1"><c r="B5" s="12"><v>39844</v></c><c r="C5" s="8"/><c r="D5" s="8"/><c r="E5" s="8"/><c r="F5" s="8"/><c r="G5" s="8"/><c r="H5" s="12"><v>39872</v></c><c r="I5" s="8"/><c r="J5" s="8"/><c r="K5" s="8"/><c r="L5" s="8"/><c r="M5" s="8"/><c r="N5" s="12"><v>39903</v></c></row></sheetData></worksheet>
code exemple qui illustre le problème:
Notez que Un est sorti après _xmlReader.Read()
, B après ReadToDescendant
, et C après ReadElementContentAsObject
.
while (reader.Read())
{
if (reader.NodeType != XmlNodeType.Whitespace) outStream.WriteLine(String.Format("*A* NodeType: {0}, Name: '{1}', Empty: {2}, Value: '{3}'", reader.NodeType, reader.Name, reader.IsEmptyElement, reader.Value));
if (reader.NodeType == XmlNodeType.Element && reader.Name == "c")
{
string a_s = reader.GetAttribute("s");
string a_t = reader.GetAttribute("t");
string a_r = reader.GetAttribute("r");
bool matchingDescendantFound = reader.ReadToDescendant("v");
if (reader.NodeType != XmlNodeType.Whitespace) outStream.WriteLine(String.Format("*B* NodeType: {0}, Name: '{1}', Empty: {2}, Value: '{3}'", reader.NodeType, reader.Name, reader.IsEmptyElement, reader.Value));
object o = reader.ReadElementContentAsObject();
if (reader.NodeType != XmlNodeType.Whitespace) outStream.WriteLine(String.Format("*C* NodeType: {0}, Name: '{1}', Empty: {2}, Value: '{3}'", reader.NodeType, reader.Name, reader.IsEmptyElement, reader.Value));
}
}
Les résultats des tests pour XML avec des espaces:
*A* NodeType: XmlDeclaration, Name: 'xml', Empty: False, Value: 'version="1.0" encoding="UTF-8" standalone="yes"' *A* NodeType: Element, Name: 'worksheet', Empty: False, Value: '' *A* NodeType: Element, Name: 'sheetData', Empty: False, Value: '' *A* NodeType: Element, Name: 'row', Empty: False, Value: '' *A* NodeType: Element, Name: 'c', Empty: False, Value: '' *B* NodeType: Element, Name: 'v', Empty: False, Value: '' *A* NodeType: EndElement, Name: 'c', Empty: False, Value: '' *A* NodeType: Element, Name: 'c', Empty: True, Value: '' *B* NodeType: Element, Name: 'c', Empty: True, Value: '' ...
Les résultats des tests pour XML sans espaces:
*A* NodeType: XmlDeclaration, Name: 'xml', Empty: False, Value: 'version="1.0" encoding="UTF-8" standalone="yes"' *A* NodeType: Element, Name: 'worksheet', Empty: False, Value: '' *A* NodeType: Element, Name: 'sheetData', Empty: False, Value: '' *A* NodeType: Element, Name: 'row', Empty: False, Value: '' *A* NodeType: Element, Name: 'c', Empty: False, Value: '' *B* NodeType: Element, Name: 'v', Empty: False, Value: '' *C* NodeType: EndElement, Name: 'c', Empty: False, Value: '' *A* NodeType: Element, Name: 'c', Empty: True, Value: '' *B* NodeType: Element, Name: 'c', Empty: True, Value: '' ...
Les changements de modèle indiquent un problème dans ReadElementContentAsObject
ou peut-être la emplacement que ReadToDescendant
déplace le XmlReader à.
Est-ce que quelqu'un sait ce qui pourrait se passer ici?
Alors, avez-vous passé en revue la source de Excel Data Reader? Vous semblez impliquer que le problème réside là-dedans ... –
@silky: Oui, mon code démo est la même logique.Soit le code n'utilise pas XmlReader correctement ou il y a un bogue dans XmlReader. Très probablement le premier mais je ne peux pas voir ce qui ne va pas. –