Adjust XML output in GraphML - markup

Do you think I can adjust the xml output from GraphML?
In the GraphML wiki the tags seem to be fixed:
<graphml>
<graph>
<node>
<data></data>
</node>
<edge>
<data></data>
</edge>
</graph>
</graphml>
I saw that you can change the tag attributes.
Do you think I could customize the tags itself to something like <car></car>?

If you need to add new elements, you would have to modify the DTD. In that case, your data would no longer be GraphML, but your own standard due to the DTD customization. Here is the GraphML DTD:
<!-- ====================================================================== -->
<!-- file: graphml.dtd ======================================================
This is the Document Type Definition for the release candidate of
GraphML version 1.0 and represents a (necessarily) looser specification
than the corresponding XML Schema. It's use is discouraged, though it
may be necessary for some systems.
Usage:
SYSTEM "http://graphml.graphdrawing.org/dtds/1.0rc/graphml.dtd"
xmlns="http://graphml.graphdrawing.org/xmlns/1.0rc"
====================================================================== -->
<!-- ===============================================================-->
<!--Parameter entity for data content -->
<!--================================================================-->
<!ENTITY % GRAPHML.data.content "(#PCDATA)">
<!-- ===============================================================-->
<!--Parameter entities for attribute list extensions -->
<!--================================================================-->
<!ENTITY % GRAPHML.graphml.attrib "">
<!ENTITY % GRAPHML.locator.attrib "">
<!ENTITY % GRAPHML.graph.attrib "">
<!ENTITY % GRAPHML.node.attrib "">
<!ENTITY % GRAPHML.port.attrib "">
<!ENTITY % GRAPHML.edge.attrib "">
<!ENTITY % GRAPHML.hyperedge.attrib "">
<!ENTITY % GRAPHML.endpoint.attrib "">
<!ENTITY % GRAPHML.key.attrib "">
<!ENTITY % GRAPHML.data.attrib "">
<!ENTITY % GRAPHML.default.attrib "">
<!--============================================================-->
<!--Attributes used by each GRAPHML element-->
<!--============================================================-->
<!ENTITY % GRAPHML.common.attrib
""
>
<!--================================================================-->
<!--the graphml elements-->
<!--================================================================-->
<!ELEMENT data %GRAPHML.data.content;>
<!ATTLIST data
key IDREF #REQUIRED
id ID #IMPLIED
%GRAPHML.data.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT default %GRAPHML.data.content;>
<!ATTLIST default
%GRAPHML.default.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT key (desc?,default?)>
<!ATTLIST key
id ID #REQUIRED
for (graph|node|edge|hyperedge|port|endpoint|all) "all"
%GRAPHML.key.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT graphml (desc?,key*,(data|graph)*)>
<!ATTLIST graphml
%GRAPHML.graphml.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT graph (desc?,(((data|node|edge|hyperedge)*)|locator))>
<!ATTLIST graph
id ID #IMPLIED
edgedefault (directed|undirected) #REQUIRED
%GRAPHML.graph.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT node (desc?,((((data|port)*,graph?))|locator))>
<!ATTLIST node
id ID #REQUIRED
%GRAPHML.node.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT port (desc?,(data|port)*)>
<!ATTLIST port
name NMTOKEN #REQUIRED
%GRAPHML.port.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT edge (desc?,data*,graph?)>
<!ATTLIST edge
id ID #IMPLIED
source IDREF #REQUIRED
sourceport NMTOKEN #IMPLIED
target IDREF #REQUIRED
targetport NMTOKEN #IMPLIED
directed (true|false) #IMPLIED
%GRAPHML.edge.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT hyperedge (desc?,(data|endpoint)*,graph?)>
<!ATTLIST hyperedge
id ID #IMPLIED
%GRAPHML.hyperedge.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT endpoint (desc?)>
<!ATTLIST endpoint
id ID #IMPLIED
node IDREF #REQUIRED
port NMTOKEN #IMPLIED
type (in|out|undir) "undir"
%GRAPHML.endpoint.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT locator EMPTY>
<!ATTLIST locator
xmlns:xlink CDATA #FIXED "http://www.w3.org/TR/2000/PR-xlink-20001220/"
xlink:href CDATA #REQUIRED
xlink:type (simple) #FIXED "simple"
%GRAPHML.locator.attrib;
%GRAPHML.common.attrib;
>
<!ELEMENT desc (#PCDATA)>
<!ATTLIST desc %GRAPHML.common.attrib;>
References
Comparison between XML to SVG Transformation Mechanisms

Related

XPath: Get element with matching attribute value

I'm trying to get content from an element whose #id attribute matches the context node's #idref. For example, given the following xml (just a contrived sample)...
<doc>
<toc>
<entry idref="ch1"/>
<entry idref="ch2"/>
</toc>
<body>
<chapter id="ch1">
<title>Chapter 1</title>
<para/>
</chapter>
<chapter id="ch2">
<title>Chapter 2</title>
<para/>
</chapter>
<chapter id="ch3">
<title>Chapter 3</title>
<para/>
</chapter>
</body>
</doc>
From the [entry] element, how can I get the content of [title] within [chapter] whose #id matches the current #idref.
So, basically find chapter[where chapter #id = current entry #idref]/title
I've tried
string(//chapter[#id = #idref]/title)
string(//chapter[#id = ./#idref]/title)
string(//chapter[#id = current()/#idref]/title)
all with no luck.
Can you try this expression on your xml?
//chapter[#id=//toc/entry/#idref]/string-join((title,#id),' ')
Output:
Chapter 1 ch1
Chapter 2 ch2

Ruby: Insert new XML element into existing XML file

How can I insert another XML element into an XML file I'm creating with Builder::XmlMarkup? e.g., something like
xml = Builder::XmlMarkup.new( :indent => 4 )
xml.content
xml.common do
xml.common_field1 do
// common_field1 content
end
xml.common_field2 do
// common_field 2 content
end
end
xml.custom do
xml.insert!(<XML element>)
end
end
Where <XML element> looks something like
<elements>
<element>
// element content
</element>
<element>
// element content
</element>
<elements>
and the final output looks like
<content>
<common>
<content1>
<!-- content1 -->
</content1>
<content2>
<!-- content2 -->
</content2>
</common>
<custom>
<elements>
<element>
<!-- element content -->
</element>
<element>
<!-- element content -->
</element>
</elements>
</custom>
</content>
I've tried using the << operator but that doesn't unfortunately doesn't maintain formatting.
<< is exactly what you need:
xml.custom do |custom|
custom << '<XML element>'
end
Rubydocs doesn't seem to work, so here's the link to the source code: https://github.com/jimweirich/builder/blob/master/lib/builder/xmlbase.rb#L104

XPath expression where attribute with a suffix matches another element's attribute w/o the suffixes?

I am looking for an XPath expression that selects the hims that have parent, gramps's with name's that have the same root name with the hims having a Jr suffix and there is a store name that looks like it is named after a gramps. In the example below that would only be Bill.
<root>
<gramps name="Bill">
<him name="Bill Jr">
<kid name="Bill III"></kid>
</him>
</gramps>
<gramps name="Tom">
<him name="Al">
<kid name="Al Jr"></kid>
</him>
</gramps>
<gramps name="Bob">
<him name="Bob Jr">
<kid name="Sam"></kid>
</him>
</gramps>
<store name="Bill's" />
<store name="Tom's" />
<store name="Pete's" />
</root>
I think this will select what you need...
/*/gramps[../store/#name=concat(#name,"'s")]/him[#name=concat(../#name,' Jr')]
This will select Bill Jr because you said you wanted to select the him.
If you want to select the gramps (Bill), just put him in a predicate...
/*/gramps[../store/#name=concat(#name,"'s")][him[#name=concat(../#name,' Jr')]]

XPath in Nokogiri returning empty array [] whereas I am expecting to have results

I am trying to parse XML files using Nokogiri, Ruby and XPath. I usually don't encounter any problem but with the following I can't make any xpath request:
doc = Nokogiri::HTML(open("myfile.xml"))
doc.("//Meta").count
# result ==> 0
doc.xpath("//Meta")
# result ==> []
doc.xpath(.).count
# result => 1
Here is an simplified version of my XML File
<Answer xmlns="test:com.test.search" context="hf%3D10%26target%3Dst0" last="0" estimated="false" nmatches="1" nslices="0" nhits="1" start="0">
<time>
...
</time>
<promoted>
...
</promoted>
<hits>
<Hit url="http://www.test.com/" source="test" collapsed="false" preferred="false" score="1254772" sort="0" mask="272" contentFp="4294967295" did="1287" slice="1">
<groups>
...
</groups>
<metas>
<Meta name="enligne">
<MetaString name="value">
</MetaString>
</Meta>
<Meta name="language">
<MetaString name="value">
fr
</MetaString>
</Meta>
<Meta name="text">
<MetaText name="value">
<TextSeg highlighted="false" highlightClass="0">
La
</TextSeg>
</MetaText>
</Meta>
</metas>
</Hit>
</hits>
<keywords>
...
</keywords>
<groups>
...
</groups>
How can I get all children of <Hit> from this XML?
Include the namespace information when calling xpath:
doc.xpath("//x:Meta", "x" => "test:com.test.search")
You can use the remove_namespaces! method and save your day.
This is one of the most FAQ XPAth questions -- search for "XPath default namespace".
If there is no way to register a namespace for the default namespace and use the registered prefix (say "x" in //x:Meta) then use:
//*[name() = 'Meta` and namespace-uri()='test:com.test.search']
If it is known that Meta can only belong to the default namespace, then the above can be shortened to:
//*[name() = 'Meta`]

How to reference an XML attribute using XPath?

My XML:
<root>
<cars>
<makes>
<honda year="1995">
<model />
<!-- ... -->
</honda>
<honda year="2000">
<!-- ... -->
</honda>
</makes>
</cars>
</root>
I need a XPath that will get me all models for <honda> with year 1995.
so:
/root/cars/makes/honda
But how to reference an attribute?
"I need a XPath that will get me all models for <honda> with year 1995."
That would be:
/root/cars/makes/honda[#year = '1995']/model
Try /root/cars/makes/honda/#year
UPDATE: reading your question again:
/root/cars/makes/honda[#year = '1995']
Bottom line is: use # character to reference xml attributes.

Resources