SVG icon indicating copy to clipboard operation
SVG copied to clipboard

GetXML does not output added child elements

Open JohnGoldsmith opened this issue 4 years ago • 12 comments

Hi,

I'm having trouble getting back the correct XML after adding sub elements to an SvgDocument

Given the following svg in a file "Min.svg":

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xml:space="preserve">
  <g transform="translate(5, 5)">
    <rect width="25" height="50" />
  </g>
</svg>

and the following code:

void Main()
{
	var path = @"C:\Users\USERNAME\Desktop\Min.svg";
	var svgDoc = SvgDocument.Open(path);
	var grp = svgDoc.Children.OfType<SvgGroup>().FirstOrDefault();
	if (grp != null)
	{
		for (int i = 1; i < 3; i++)
		{
			grp.Children.Add(new SvgCircle
			{
				CenterX = 10 * i,
				CenterY = 10 * i,
				Radius = 50
			});
		}
	}
	svgDoc.GetXML().Dump();
}

This (LINQPad) sample outputs the following text (without the SvgCircle elements being displayed):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg d1p1:space="preserve" ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1" xmlns:d1p1="http://www.w3.org/XML/1998/namespace" xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(5, 5)">
    <rect width="100" height="50" />
  </g>
</svg>

My main question is where are the added elements?

Other questions are why does the d1p1 alias get added and, also is it correct that the xmlns:ev="http://www.w3.org/2001/xml-events" gets picked up as a custom attribute (SvgDocument.CustomAttributes)?

Many thanks for any insight

John

NuGet version 3.2.3 .Net Framework 4.8 Windows 10 Pro 20H2 (build 19042)

JohnGoldsmith avatar Jan 21 '21 18:01 JohnGoldsmith

I deleted my original comment as it was misleading.

The problem seems to be the xml:space="preserve" in the original image. Removing this fixes the problem, so I would guess that there is a bug in handling this attribute. I don't know the related code, but I'm flagging this as a bug for now - maybe someone with more insight has an idea.

mrbean-bremen avatar Jan 21 '21 20:01 mrbean-bremen

@mrbean-bremen

The problem seems to be the xml:space="preserve" in the original image.

From PR #760, this problem has occurred.

Since there are many differences, I do not know unless check it properly, but I presume that the cause is probably here.

H1Gdev avatar Jan 22 '21 00:01 H1Gdev

Apparently, XmlTextWriter LookupPrefix method doesn't seem to work as expected. (null will be returned.)

It seems that need to consider that it will be null.

H1Gdev avatar Jan 22 '21 01:01 H1Gdev

@JohnGoldsmith If outputting as XML, please do as follows.

void Main()
{
	var path = @"C:\Users\USERNAME\Desktop\Min.svg";
	var svgDoc = SvgDocument.Open(path);
	var grp = svgDoc.Children.OfType<SvgGroup>().FirstOrDefault();
	if (grp != null)
	{
		for (int i = 1; i < 3; i++)
		{
                        var element = new SvgCircle
			{
				CenterX = 10 * i,
				CenterY = 10 * i,
				Radius = 50
			};
			grp.Children.Add(element);
			grp.Nodes.Add(element); // need this, too...
		}
	}
	svgDoc.GetXML().Dump();
}

I think this is a very confusing interface for users...

H1Gdev avatar Jan 22 '21 02:01 H1Gdev

That's great. Thanks very much to you both for your really fast response and for the workaround of adding to both collections. I confirm that works for me as well.

Seems like Children adds some duplication of Nodes...still I'm glad to be up and working.

Thanks again.

John

JohnGoldsmith avatar Jan 22 '21 12:01 JohnGoldsmith

After upgrading to version 3.3.0 from 3.2.3 I was also affected with this problem. Does this mean that after 3.3.0, whenever I add/remove svg elements from Children, the same operations must be duplicated also on Nodes? How about using .Clear and .Insert?

Note that I am manipulating SVG files created by Inkscape.

I'm using this following method to save them, but the same problem occurs.

using (var ms = new MemoryStream())
{
    doc.Write(ms, false);
    return Encoding.UTF8.GetString(ms.ToArray());
}

Please let me know if you would like a small project demonstrating the problem.

hakakou avatar Sep 24 '21 17:09 hakakou

@H1Gdev - can you have a look please? I won't have access to a computer for a week.

mrbean-bremen avatar Sep 24 '21 19:09 mrbean-bremen

@hakakou

After upgrading to version 3.3.0 from 3.2.3 I was also affected with this problem. Does this mean that after 3.3.0, whenever I add/remove svg elements from Children, the same operations must be duplicated also on Nodes? How about using .Clear and .Insert?

Regarding the operation of Children, I think that the change from 3.2.3 to 3.3.0 has not changed.

Please let me know if you would like a small project demonstrating the problem.

Please create new issue and report problem.

H1Gdev avatar Sep 24 '21 22:09 H1Gdev

@mrbean-bremen This issue can be closed.

H1Gdev avatar Oct 19 '21 22:10 H1Gdev

@H1Gdev - What about the issue mentioned by @hakakou? Shouldn't there be a new issue for this?

mrbean-bremen avatar Oct 20 '21 06:10 mrbean-bremen

@mrbean-bremen It seems to branch to # 905.

H1Gdev avatar Oct 20 '21 07:10 H1Gdev

Yes, but that's a PR, not an issue. It would help to have an issue to track this.

mrbean-bremen avatar Oct 20 '21 07:10 mrbean-bremen