测试之前解析XPS文档的时候,出现的解析XpsDocument的节点不结构化问题,实验了很多解决方案都失败了,在LINQ和lambda表达式按多个字段排序上得到启发,找到解决办法。解决方案如下:
(1)根据XpsDocument每个Glyphs节点的比例值、偏移量等属性重新计算该节点实际的X,Y坐标;
(2)将计算好的X,Y坐标和节点值存到类;
(3)按照Y坐标先分组后排序,按照X坐标先分组后排序,然后保存到集合中;
(4)遍历集合,按指定格式输出节点内容。
代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Windows.Xps.Packaging; 7 using System.Xml; 8 using System.Xml.Serialization; 9 10 namespace 自助打印机工作站 11 { 12 class XpsOperationClass 13 { 14 public static String GetXpsText(string strPath) 15 { 16 string strXml = ""; 17 try 18 { 19 #region 获取数据 20 XmlConfig config = new XmlConfig(); 21 XpsDocument xpsDocument = new XpsDocument(strPath, FileAccess.Read); 22 var reader = xpsDocument.FixedDocumentSequenceReader; 23 foreach (var document in reader.FixedDocuments) 24 { 25 foreach (var page in document.FixedPages) 26 { 27 XmlReader xrdr = page.XmlReader; 28 29 while (xrdr.Read()) 30 { 31 switch (xrdr.NodeType) 32 { 33 case XmlNodeType.Element: 34 if (xrdr.Name == "Glyphs") 35 { 36 ConfigItem conitem = new ConfigItem(); 37 conitem.OriginX = Convert.ToDouble(xrdr["OriginX"]); 38 conitem.OriginY = Convert.ToDouble(xrdr["OriginY"]); 39 //获取比例值 40 conitem.RenderTransform = xrdr["RenderTransform"] ?? "1"; 41 //获取比例值 42 conitem.RenderTrans = Convert.ToDouble(conitem.RenderTransform.Split(',')[0]); 43 //检查是否存储了相似的 Y值,因为后期输出的与原值 有偏差,偏差不大 44 double pcvalue = 8d;//上下偏差值 45 ConfigItem tempItem = config.Params.Find(q => q.OriginYrms < conitem.OriginY * conitem.RenderTrans + pcvalue && q.OriginYrms > conitem.OriginY * conitem.RenderTrans - pcvalue); 46 //如果有就取原值,利用原值下面将分组,设置相同以后才能确定是同一行 47 if (tempItem != null) 48 { 49 conitem.OriginYrms = tempItem.OriginYrms; 50 } 51 else 52 { 53 //如果没有设置新的 与比例相乘,得到正常的值的Y 54 conitem.OriginYrms = conitem.OriginY * conitem.RenderTrans; 55 } 56 //与比例相乘,得到正常的值的X 57 conitem.OriginXrms = conitem.OriginX * conitem.RenderTrans; 58 conitem.UnicodeString = xrdr["UnicodeString"]; 59 config.Params.Add(conitem); 60 } 61 break; 62 default: break; 63 } 64 } 65 xrdr.Close(); 66 } 67 } 68 xpsDocument.Close(); 69 #endregion 70 #region 排序数据 71 //创建新的 配置文件对象 72 XmlConfig sortConfig = new XmlConfig(); 73 //先分组,等同于分行,将所有的行分开 74 var groupParam = config.Params.GroupBy(p => p.OriginYrms) 75 .Select(g => new { ConfigItemList = g.ToList(), count = g.Count(), Key = g.Key }).ToList(); 76 //排序,正序,即:第一行、第二行、第三行。。。。。 77 foreach (var gp in groupParam.OrderBy(p => p.Key)) 78 { 79 //排序获取列,即:第一列、第二列。。。。。。 80 List<ConfigItem> paramorder = gp.ConfigItemList.OrderBy(p => p.OriginXrms).ToList(); 81 foreach (var item in paramorder) 82 { 83 sortConfig.Params.Add(item);//将内容填充到新的对象中 84 } 85 } 86 87 foreach (ConfigItem item in sortConfig.Params) 88 { 89 if (item.UnicodeString.IndexOf(":") >= 0 || item.UnicodeString.IndexOf(":") >= 0) 90 { 91 //原始内容 92 strXml += item.UnicodeString; 93 } 94 else 95 { 96 strXml += item.UnicodeString + " "; 97 } 98 } 99 #endregion 100 } 101 catch (Exception ex) 102 { 103 strXml = string.Empty; 104 } 105 return strXml; 106 } 107 } 108 public class XmlConfig 109 { 110 111 public XmlConfig() 112 { 113 Params = new List<ConfigItem>(); 114 } 115 [XmlElement("Glyphs")] 116 public List<ConfigItem> Params { get; set; } 117 } 118 public class ConfigItem //: IComparable 119 { 120 [XmlText] 121 public string Value { get; set; } 122 [XmlAttribute("RenderTransform")] 123 public string RenderTransform { get; set; } 124 /// <summary> 125 /// 缩放比例 126 /// </summary> 127 [XmlIgnore] 128 public double RenderTrans { get; set; } 129 [XmlAttribute("Fill")] 130 public string Fill { get; set; } 131 [XmlAttribute("FontUri")] 132 public string FontUri { get; set; } 133 [XmlAttribute("FontRenderingEmSize")] 134 public string FontRenderingEmSize { get; set; } 135 [XmlAttribute("StyleSimulations")] 136 public string StyleSimulations { get; set; } 137 [XmlAttribute("OriginX")] 138 public double OriginX { get; set; } 139 /// <summary> 140 /// 计算正常比例 X 141 /// </summary> 142 [XmlAttribute("OriginXrms")] 143 public double OriginXrms { get; set; } 144 /// <summary> 145 /// 计算正常比例 Y 146 /// </summary> 147 [XmlAttribute("OriginY")] 148 public double OriginY { get; set; } 149 [XmlAttribute("OriginYrms")] 150 public double OriginYrms { get; set; } 151 [XmlAttribute("Indices")] 152 public string Indices { get; set; } 153 [XmlAttribute("UnicodeString")] 154 public string UnicodeString { get; set; } 155 156 } 157 }