如何指定 XPath 以生成包含与其父元素属性连接的元素文本的列表
Posted
技术标签:
【中文标题】如何指定 XPath 以生成包含与其父元素属性连接的元素文本的列表【英文标题】:How to specify XPath to produce a list containing element text concatenated with its parent element attribute 【发布时间】:2021-08-21 22:50:34 【问题描述】:我还是 XPath 的新手,并试图处理具有一些复杂结构的大型数据集。以下是一些示例数据:
...
<div2 id="n104226" key="to/lmh" type="main">
<headword extent="suff" lang="greek">τόλμη</headword>,
<gen lang="greek">ἡ</gen>,
<sense id="n104226.0" n="A">v. τόλμα.</sense>
</div2>
<div2 id="n104244" key="*to/maros" type="main">
<headword extent="full" lang="greek">Τόμαρος</headword>,
<gen lang="greek">ὁ</gen>,
<sense id="n104244.0" n="A">v. Τομοῦροι.</sense>
</div2>
<div2 id="n104248" key="tomei=on" type="main">
<headword extent="suff" lang="greek">τομεῖον</headword>,
<gen lang="greek">τό</gen>,
</div2>
...
我想生成一个词条列表,以及父元素 (div2) 上的 key 属性,如下所示:
...
τόλμη, to/lmh
Τόμαρος, *to/maros
τομ-εῖον, tomei=on
...
我在这里查看了许多关于 SO 的帖子以获得想法,例如:
How to get the attribute value of a parent element in Xpath if Child element exists? Xpath query to get the parent Element text and its child element attribute values? How to get a specifc information for an XML file Parse XML based on attributes and text values of related nodes Concatenate multiple node values in xpath我曾多次尝试定义 XPath 表达式来执行此操作,但均未成功。我一直在使用 XML Copy Editor 的 Evaluate XPath 功能尝试这些表达式,但最终我想在我的 C# 代码中使用该表达式,所以我都尝试了。以下是我尝试过的一些表达方式:
//div2/string-join(@key | headword, "<>")
//div2/concat(@key, ' ', headword/text())
//div2/concat(@key, ',', headword[1])
每次XML Copy Editor都会给我这个错误信息:
无法评估 XPath:第 0 行出错:表达式无效
同时,.NET 抛出如下形式的异常:
"'//div2/concat(@key, ',', headword1)' 的令牌无效。"
IIRC,当我的同事在 Oxygen 中尝试时,这最后一个为他工作。
我在XML Copy Editor中试过这个:
concat(//div2/@key, ',', //div2/headword/text())
它没有产生错误消息,但它只产生了第一个结果。
谁能帮我解决这个问题?
为了完整起见,这里是我的 C# 代码的片段:
XPathNavigator navigator = ResourceDocument.CreateNavigator();
XPathNodeIterator nodeSetTmp =
navigator.Select(@"//div2/headword[1]/text()", nsmgr);
感谢您的任何建议...
更新
这里还有一些我尝试过的 XPath 表达式(但没用):
//div2 ! string-join((headword, " ", @key), "")
//div2/string-join((headword, " ", @key), "")
//div2/concat(headword, " ", @key)
【问题讨论】:
【参考方案1】:你想要的结果与你的努力不匹配......但这可能是一个小错误。 (切换@key
和headword
)
这两个 XPath 工作正常:
//div2/concat(@key, ' ', headword/text())
//div2/concat(@key, ',', headword[1])
氧气正在显示这个结果:
to/lmh,τόλμη
*to/maros,Τόμαρος
tomei=on,τομεῖον
也许您使用的 XPath 引擎是 1.0?
作为替代方案,您可以尝试使用非常简单的 xslt 1.0,如下所示:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:template match="div2">
<xsl:value-of select="concat(headword[1]/text(),', ',@key)"/>
</xsl:template>
</xsl:transform>
会给出这个结果。
τόλμη, to/lmh
Τόμαρος, *to/maros
τομεῖον, tomei=on
【讨论】:
"也许您使用的 XPath 引擎是 1.0?"是的,事实证明,由于各种原因,我们还不能升级。所以这是它不起作用的主要原因。谢谢,@Siebe。以上是关于如何指定 XPath 以生成包含与其父元素属性连接的元素文本的列表的主要内容,如果未能解决你的问题,请参考以下文章
如何指定一个元素以具有一个属性,该属性说明它在 XML 模式中包含多少个子元素?