If your XML is big, it will lead to a bad performance, if you first shred the whole thing, just to filter it afterwards. It is better to include your filter as predicate into your XQuery:
DECLARE @xml XML=
N'<metadata>
<meta id="TypeX" valuetype="xs:string">
<values>
<value>3</value>
</values>
</meta>
<meta id="TypeY" valuetype="xs:string">
<values>
<value>5</value>
<value>6</value>
</values>
</meta>
</metadata>';
--This is the variable holding the id's value
DECLARE @id VARCHAR(10)='TypeX';
--This SELECT reads the first <value> within <values> as one-liner:
SELECT @xml.value(N'(/metadata/meta[@id=sql:variable("@id")]/values/value/text())[1]','int');
--Change the filter-variable
SET @id='TypeY'
--This query will use .nodes() to get all <value> nodes within <values> (if there are more of them)
SELECT v.value('text()[1]','int')
FROM @xml.nodes(N'/metadata/meta[@id=sql:variable("@id")]/values/value') AS A(v);
One more hint: If you are sure, that there is only one entry per @id, you might extend the predicate to [@id=sql:variable("@id")][1]. This will prevent the engine to continue searching for nodes with this id.