2013-02-21 48 views
5

XPath的ID()我有以下XML文档:替代在.NET

<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是XPath表达式,它指向<gloss xml:id="TDPV">元件。

我使用LINQ-to-XML来选择它。

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

我得到以下异常:System.NotSupportedException: This XPathNavigator does not support IDs.

,所以我试图与其他表达式替换id()我无法找到一个解决这个问题:

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

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

但这些作品。

有没有办法实现id()或用另一个表达式替换它?

我宁愿一个解决方案/解决方法,不涉及用另一个表达式替换id(),因为这个表达式可能像id(@def) | id(//*[@attr="(id(@abc()))))))"])那样复杂。

+1

如果源XML文档具有DTD w,那么'id()'函数才能正常工作第i个被定义为ID的元素 - 在任何兼容的XPath实现中,没有这样的DTD,都不希望id()函数按需要进行评估。如果满足这个先决条件,则可以尝试将XDocument转换为普通的XMLDocument(或XpathNavigator)并使用'SelectNodes()'(或'Evaluate()')方法。 – 2013-02-21 15:39:24

+0

下面是一个在Java中工作的解决方法:http://lists.w3.org/Archives/Public/public-multilingualweb-lt-tests/2013Jan/0064.html – mak 2013-02-24 18:07:14

+0

mak,所提到的java解决方法在您的情况下不起作用。您需要编写一个评估方法,该方法接受一个字符串,表示一个XPath表达式并对其进行评估。您将使用此方法生成的结果来构造最终的XPath表达式,该表达式将选择“id”属性具有该值的元素。 – 2013-02-24 18:29:25

回答

5

如果def属性是保证在XmlDocument的,使用中只能出现一次:

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

如果有可能不同def属性,那么你需要提供选择完全想XPath表达式def属性在您的情况:

//*[@xml:id = someExpressionSelectingTheWantedDefAttribute] 

XSLT - 基于验证:

<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> 

当这个变换所提供的XML文档应用:

<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> 

XPath表达式求值和该评价(所选元素)的结果将被复制到输出

<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> 
+0

感谢您使用基于XSLT的验证示例,我不知道这一点。我不知道“def”可以出现多少次,或者即使它是一个属性。我想我可以通过'id(./id/text())'表达式来' TDPV ...''。我希望有一个XPath函数,我不知道它会评估一个表达式并返回一个值,我可以在'// * [@ xml:id = evaluate(@def)]中使用' – mak 2013-02-24 18:04:37

+0

@mak,如果你要求*动态评估*,即使在XPath 3.0中也是不可能的(在XSLT 4.0中可能使用新指令'')。但在我看来,你不需要在这里进行动态评估 - 只需手动指定带来要比较的值的表达式即可。 – 2013-02-24 18:20:23