Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to XPath id() in .NET

I have the following XML document:

<text xmlns:its="http://www.w3.org/2005/11/its" >
 <its:rules version="2.0">
  <its:termRule selector="//term" term="yes" termInfoPointer="id(@def)"/>
 </its:rules>
 <p>We may define <term def="TDPV">discoursal point of view</term>
 as <gloss xml:id="TDPV">the relationship, expressed through discourse
  structure, between the implied author or some other addresser,
  and the fiction.</gloss>
 </p>
</text>

termInfoPointer is an XPath expression which points to the <gloss xml:id="TDPV"> element.

I use LINQ-to-XML to select it.

XElement term = ...;
object value = term.XPathEvaluate("id(@def)");

I get the following exception: System.NotSupportedException: This XPathNavigator does not support IDs.

I couldn't find a solution to this problem so I tried to replace id() with other expressions:

//*[@xml:id='TDPV'] // works, but I need to use @def

//*[@xml:id=@def]
//*[@xml:id=@def/text()]
//*[@xml:id=self::node()/@def/text()]

but none of these works.

Is there a way to implement id() or replace it with another expression?

I'd prefer a solution/workaround that doesn't involve replacing id() with another expression because this expression could be something complex like id(@def) | id(//*[@attr="(id(@abc()))))))"]).

like image 416
mak Avatar asked Feb 21 '13 14:02

mak


1 Answers

If the def attribute is guaranteed to appear only once in the XMLdocument, use:

//*[@xml:id = //@def]

If there might be different def attributes, then you need to provide an XPath expression that selects exactly the wanted def attribute in your case:

//*[@xml:id = someExpressionSelectingTheWantedDefAttribute]

XSLT - based verification:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
     <xsl:copy-of select="//*[@xml:id = //@def]"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<text xmlns:its="http://www.w3.org/2005/11/its" >
 <its:rules version="2.0">
  <its:termRule selector="//term" term="yes" termInfoPointer="id(@def)"/>
 </its:rules>
 <p>We may define <term def="TDPV">discoursal point of view</term>
 as <gloss xml:id="TDPV">the relationship, expressed through discourse
  structure, between the implied author or some other addresser,
  and the fiction.</gloss>
 </p>
</text>

the XPath expression is evaluated and the result of this evaluation (the selected element) is copied to the output:

<gloss xmlns:its="http://www.w3.org/2005/11/its" xml:id="TDPV">the relationship, expressed through discourse
  structure, between the implied author or some other addresser,
  and the fiction.</gloss>
like image 109
Dimitre Novatchev Avatar answered Sep 27 '22 16:09

Dimitre Novatchev