Having this sample SVG (which gets created in Microsoft Visio):
<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"
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="34.6243in" height="10.4874in"
viewBox="0 0 2492.95 755.093" xml:space="preserve" color-interpolation-filters="sRGB" >
<g id="shape1014-243" v:mID="1014" v:groupContext="shape" transform="translate(30.3431,-54.0037)">
<title>Team frame.1171</title>
<desc>Test</desc>
<v:custProps>
<v:cp v:nameU="Theme" v:lbl="MY_UNIQUE_ID_1" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="0" v:cal="0" v:val="VT0(0):26"/>
</v:custProps>
<v:textBlock v:margins="rect(0,0,0,0)" v:tabSpace="42.5197"/>
<v:textRect cx="100.34" cy="791.095" width="200.69" height="72.0035"/>
<path d="M56.21 84.35 L55.85 84.35 L17.01 84.35 A17.0079 17.0079 -180 0 0 0 101.35 L0 738.09 A17.0079 17.0079 -180 0
0 17.01 755.09 L183.67 755.09 A17.0079 17.0079 -180 0 0 200.68 738.09 L200.68 101.35 A17.0079 17.0079 -180
0 0 183.67 84.35 L144.83 84.35" />
<text x="5.13" y="809.09" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>Arrivals</text>
</g>
</svg>
I want to access the 'g' element. The problem is I can't simply use document.getElementById("shape1014-243"); as the ID will be randomly generated by Visio.
The value which I know I can access it by, is this value v:lbl="MY_UNIQUE_ID_1". Now, how can I access the 'g' element knowing only that value?
I can do the following:
- Get all v:cp elements with var elements = document.getElementsByTagName("v:cp");
- Loop through them and check if elements[X].getAttribute("v:lbl") === "MY_UNIQUE_ID_1"
- If true, then get the 'g' element using element[X].parentElement.parentElement
But is there a better way? I tried document.querySelector('[v:lbl="MY_UNIQUE_ID_1"]'); but it returns error 'not a valid selector'.
I tried the code in the question. I am expecting a solution
CodePudding user response:
I would probably start with searching for the element you actually know :
let elem = document.querySelector(`*[v\\:lbl="MY_UNIQUE_ID_1"]`);
(note the \\
escaping the colon)
Then use this and loop on elem.parentElement
then its parent element and so on until I find one that has nodeName
as g
. (Unfortunately CSS does not have a way to select an element that contains another specific element -- that I know of at least)
This works:
let elem = document.querySelector(`*[v\\:lbl="MY_UNIQUE_ID_1"]`);
while(elem != null && elem.nodeName != `g`){
elem = elem.parentNode;
}
if(elem !== null){
// do something with elem
}
CodePudding user response:
Streamlining what you already proved to work:
Find the element by your known, unique label get the closest g element ( parentElement.parentElement )
the example below will log the id of the g element, so shows "shape1014-243"
function getG( uniqueLabel ){
var elementOne = document.querySelector(`v\\:cp[v\\:lbl='${uniqueLabel}']`);
return elementOne.closest('g');
}
function logGetG( uniqueLabel ){
console.log(getG(uniqueLabel).id);
}
<button onClick='logGetG("MY_UNIQUE_ID_1");'>Get G!</button>
<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"
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="34.6243in" height="10.4874in"
viewBox="0 0 2492.95 755.093" xml:space="preserve" color-interpolation-filters="sRGB" >
<g id="shape1014-243" v:mID="1014" v:groupContext="shape" transform="translate(30.3431,-54.0037)">
<title>Team frame.1171</title>
<desc>Test</desc>
<v:custProps>
<v:cp v:nameU="Theme" v:lbl="MY_UNIQUE_ID_1" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="0" v:cal="0" v:val="VT0(0):26"/>
</v:custProps>
<v:textBlock v:margins="rect(0,0,0,0)" v:tabSpace="42.5197"/>
<v:textRect cx="100.34" cy="791.095" width="200.69" height="72.0035"/>
<path d="M56.21 84.35 L55.85 84.35 L17.01 84.35 A17.0079 17.0079 -180 0 0 0 101.35 L0 738.09 A17.0079 17.0079 -180 0
0 17.01 755.09 L183.67 755.09 A17.0079 17.0079 -180 0 0 200.68 738.09 L200.68 101.35 A17.0079 17.0079 -180
0 0 183.67 84.35 L144.83 84.35" />
<text x="5.13" y="809.09" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>Arrivals</text>
</g>
</svg>