我正在阅读带有XmlTextReader
的svg / xml,我想在新的svg / xml文件中写回一些元素
<svg>
<rect x="135.7" y="537.4" fill="none" stroke="#000000" stroke-width="0.2894" width="36.6" height="42.2"/>
<rect x="99" y="537.4" fill="#A0C9EC" stroke="#000000" stroke-width="0.2894" width="36.7" height="42.2"/>
</svg>
我想要填充“none”的rect元素,所以我开始阅读和写作
var reader = new XmlTextReader(file.InputStream);
var writer = new XmlTextWriter(svgPath + fileNameWithoutExtension + "-less" + extension, null);
writer.WriteStartDocument();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "svg")
{
writer.WriteStartElement(reader.Name);
while(reader.MoveToNextAttribute()){
writer.WriteAttributes(reader, true);
}
}
if (reader.Name == "rect" || reader.Name == "polygon")
{
while(reader.MoveToNextAttribute()){
if(reader.Name == "fill" && reader.value == "none"){
writer.WriteStartElement(reader.Name);
writer.WriteAttributes(reader, true);
writer.WriteEndElement();
}
}
}
break;
case XmlNodeType.EndElement:
break;
default:
break;
}
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
但是返回一个带有“fill”元素且没有“x”和“y”属性的文件(因为WriteAttributes
从当前位置读取而读者位于fill属性中)
<svg>
<fill="none" stroke="#000000" stroke-width="0.2894" width="36.6" height="42.2"/>
</svg>
有没有办法得到我想要的结果?我不想使用XmlDocument
,因为我的svg文件很大,需要很长时间来加载XmlDoc.Load
由于
答案 0 :(得分:3)
尝试以下方法;你可以适应:
if (reader.Name == "rect" || reader.Name == "polygon")
{
string fill = reader.GetAttribute("fill"); //Read ahead for the value of the fill attr
if(String.Compare(fill, "none", StringComparison.InvariantCultureIgnoreCase) == 0) //if the value is what we expect then just wholesale copy this node.
{
writer.WriteStartElement(reader.Name);
writer.WriteAttributes(reader, true);
writer.WriteEndElement();
}
}
请注意,GetAttribute不会移动阅读器,使您可以保留在rect或polygon节点的上下文中。
您也可以尝试使用单个reader修改您的第一次尝试.MoveToFirstAttribute() - 我没有测试过,但它应该让您回到当前节点的第一个元素。
您可能还想调查XPathDocument类 - 这比XmlDocument轻很多但是您仍然首先将整个结构加载到内存中,因此可能不合适 - 选择您想要的节点然后只是使用的XPath:
//rect[@fill='none'] || //polygon[@fill='none']
最后,您还可以使用XSLT。如果您想为源文档发布更完整的结构,我很乐意为您编写一个。
答案 1 :(得分:2)
这是使用命令式C#的讨厌的业务,您可以考虑使用XSLT: http://www.w3schools.com/xsl/el_value-of.asp
答案 2 :(得分:2)
在调用MoveToNextAttribute之前,需要将reader.Name存储在变量中。然后,当您调用WriteStartElement时,请改用该值。
if (reader.Name == "rect" || reader.Name == "polygon")
{
// get tag name here
var tagName = reader.Name;
while(reader.MoveToNextAttribute()){
if(reader.Name == "fill" && reader.value == "none"){
// write tag name here
writer.WriteStartElement(tagName);
writer.WriteAttributes(reader, true);
writer.WriteEndElement();
}
}
}