Loading...
Logo
Processing Forum

“The Extensible Markup Language XML has become the standard for exchanging structured data in Internet applications. proXML allows you to easily integrate and manipulate this data in Processing.”

http://creativecomputing.cc/p5libs/proxml/index.htm

I have this file generated in Inkscape - drawing08.svg - with one rectangle. It basically includes the following:

Copy code
  1. <svg
  2.   <defs…
  3.   <sodipodi…
  4.   <metadata…
  5.   <g
  6.      inkscape:label="Layer 1"
  7.      inkscape:groupmode="layer"
  8.      id="layer1"
  9.      transform="translate(-8.5714245,593.94476)">
  10.     <rect…
  11.   </g>
  12. </svg>

Sketch xml_02 includes this code:

Copy code
  1. import proxml.XMLInOut;
  2. import proxml.XMLElement;
  3. XMLInOut xmlIO;
  4. void setup()
  5. {
  6.   size(400, 400);
  7.   main = loadShape("drawing08.svg");
  8.  
  9.   xmlIO = new XMLInOut(this);
  10.   xmlIO.loadElement("drawing08.svg"); // Use this method to load an xml file.
  11.   noLoop();
  12. }
  13. void xmlEvent(XMLElement element) {

 Add this code:

Copy code
  1.   // get children of root element
  2.   XMLElement[] children = element.getChildren();
  3.   for(int i = 0; i < children.length;i++)
  4.   {
  5.     XMLElement child = children[i];
  6.     println("child index: " + str(i) + child);
  7.   }

Console shows:

children index: 0<defs…

children index: 1<sodipodi…

children index: 2<metadata…

children index: 3<g…

 

Add this code:

Copy code
  1.  // get attributes for child 3 - <g   
  2. Println(“children[3]”); 
  3. String[] attributes = children[3].getAttributes();
  4.   for(int j = 0; j < attributes.length; j++)
  5.   {
  6.     println("attributes index: " + str(j) + attributes[j]);
  7.   }

Console shows:

children[3]

attributes index: 0inkscape:label

attributes index: 1transform

attributes index: 2inkscape:groupmode

attributes index: 3id


Question: Why are attributes assigned in different order than svg file?

 

Add this code:

Copy code
  1.   // look for attribute "transform"
  2.   for(int k = 0; k < attributes.length; k++)
  3.   {
  4.     String matchAtt = "transform";
  5.     if(attributes[k] == matchAtt)
  6.     {
  7.       println(attributes[k] + " EQUAL " + matchAtt);
  8.     } 
  9.     else
  10.     {
  11.       println(attributes[k] + " NOT EQUAL " + matchAtt);
  12.     } 
  13.   }

 Console shows:

inkscape:label NOT EQUAL transform

transform NOT EQUAL transform

inkscape:groupmode NOT EQUAL transform

id NOT EQUAL transform


Question: Why is transform NOT EQUAL?  

 

Add this code:

Copy code
  1.   // get value for child[3] attributes[1]
  2.   String attValue = children[3].getAttribute(attributes[1]);
  3.   println("attValue: " + attValue);

Console shows:

attValue: translate(-8.5714245,593.94476)


Add this code:
Copy code
  1. children[3].setAttribute(attributes[1],“translate(0,0)”);
error: unexpected token: [

Questions:
Is this the correct syntax?

I know setAttribute() is not included in proXML.
But "proXML allows you to easily integrate and manipulate this data in Processing."
What manipulation is it able to do?

If proXML cannot do this, is there another library that can?

Replies(6)

" Why are attributes assigned in different order than svg file?"
Not sure, as I never used proXML (I use Processing's XMLElement or Java's standard XML handling), but the order of attributes is indifferent in XML. The library probably puts them in a hash map, which doesn't keep the order.

" Why is transform NOT EQUAL?"
Because you should never compare strings with ==
See String reference.

" Is this the correct syntax?"
The syntax looks OK, you might have an error elsewhere.
But if you " know [that] setAttribute() is not included in proXML", you probably get an error by calling a non-existing method on XMLElement.

Why are you trying to do?
- Manipulate the data once it is loaded? In this case, you probably must act on matrices and similar, not on XML elements that are already transformed to PShape.
- Automate the transformation of XML and then save back the XML? Then it might be the right approach. Processing's XML doesn't allow this, but as I wrote, you can use one of the standard XML processing facilities of standard Java, or use one of the many Java libraries around (most made before it was standard in Java), like JDom, Dom4j, Xom, and so on. See http://stackoverflow.com/questions/831865/what-java-xml-library-do-you-recommend-to-replace-dom4j for various recommendation. I found I plussed on the XMLTool recommendation, I don't remember using it, but I will follow my old choice and try it again...
XMLTool is very nice, with an easy to use API.
Example, to remove all transform attributes from g tags:
Copy code
  1. XMLTag doc = XMLDoc.from(new File("H:/Temp/Test.svg"), false);
  2. for (XMLTag tag : doc.getChilds())
  3. {
  4.   if (tag.getCurrentTagName().equals("g"))
  5.   {
  6.     if (tag.hasAttribute("transform"))
  7.     {
  8.       tag.deleteAttribute("transform");
  9.     }
  10.   }
  11. }
  12. println(doc.toString());
And this isn't necessarily the shortest way to do it.
Example of making an XML from scratch:
Copy code
  1. XMLTag tag1 = XMLDoc.newDocument(true)
  2.     .addRoot("html")
  3.     .addTag("head").addText("one")
  4.     .gotoChild("head")
  5.     .addTag("title").addText("my title 1")
  6.     .addTag("title").addText("my title 2")
  7.     .addText("")

  8.     .addTag("body")
  9.     .addTag("number").addAttribute("type", "hexa").addText("0xCAFEBABE")
  10.     .addText("two")
  11.     .gotoChild("body")
  12.     .addTag("bool").addText("true")
  13.     .gotoRoot();
  14. println(tag1.toString());
Quite nice, no?

But if you " know [that] setAttribute() is not included in proXML"
I was taking a chance that the software had more features than the web site.
It has a saveElement(), indicating that values can be changed.
I'm disappointed with proXML's website advertising that it enables easy manipulation of xml data.
Perhaps they should explain what they mean by that?

What I'm trying to do:
  • Read the svg file.
  • Modify it before Processing reads it.
Is that possible?

XMLTool is very nice, with an easy to use API.
I downloaded xmltool. When I selected it, this was automatically inserted into my code:

Copy code
  1. import com.mycila.xmltool.*;

But I can't find clear information about it as I did with proXML.
I'm not a professional programmer and find their manual confusing:



 


Thanks.
After resolving a few "problems", I'm able to see the results of your code.

Regarding your code
Copy code
  1. XMLTag doc = XMLDoc.from(new File("H:/Temp/Test.svg"), false);

I realized

> xmltool needs the path and file name (path not needed for normal svg files found in sketch Data folder).

> Windows users need to use forward slash (/) (they normally use backward slash ()).

 
Regarding your code
Copy code
  1.   if (tag.getCurrentTagName().equals("g"))
  2.   {
  3.     if (tag.hasAttribute("transform"))
  4.     {
  5.       tag.deleteAttribute("transform");
  6.     }
  7. }
  8. println(doc.toString());
The println information indicates the “transform” attribute has been deleted.

Now, to have Processing utilize this information is another thing.


XMLTool is very nice, with an easy to use API.
Perhaps it's easy for seasoned java programmers. At this point, I cannot see how you found this code in the xmltool manual. Could you please provide some clues, especially the first line that enables a data file to be read. Can "doc" be written back to the file? I imagine the file must be closed then?

" xmltool needs the path and file name (path not needed for normal svg files found in sketch Data folder)."
Yes, only Processing-specific libraries know about sketch and data paths. For regular Java libraries, you have some under-documented functions:
XMLTag doc = XMLDoc.from(dataFile(Test.svg"), false);
I use to use absolute paths because I often try things without even saving a sketch, so having no data folder.
And indeed, backslash have a special meaning in most programming languages (\n is a newline character), and even in some environments (Zoho has a bug where they interpret the backslash if followed by a char, see your own post, it has disappeared!).
So, we have either to double them to escape them (make them regular chars) or to use forward slashes, nicer IMHO, which are perfectly usable in Windows.

Write back the XML data: you have to use a PrintWriter.
I took the second example from the XMLTool examples, the first one was quickly cobbled together from the JavaDoc. I admit that finding such operation isn't easy for a beginner, even more as I knew more or less what to look for (familiarity with XML helps too...).
Yes the PrintWriter worked.

Copy code
  1.   PrintWriter output;
  2. //  output = createWriter("drawing08_new.svg"); // in same folder as sketch, not data folder
  3.   output = createWriter("data/drawing08_new.svg"); // in data folder
  4.   output.println(doc); // Write the doc to the file
  5.   output.flush(); // Writes the remaining data to the file
  6.   output.close(); // Finishes the file                                                                                                           
I was then able to read the new file 
Copy code
  1.   main = loadShape("drawing08_new.svg");

Thanks for your help.