使用 XSLT 检查节点是不是存在

Posted

技术标签:

【中文标题】使用 XSLT 检查节点是不是存在【英文标题】:Check if a node exists using XSLT使用 XSLT 检查节点是否存在 【发布时间】:2011-06-09 07:57:36 【问题描述】:

首先,我想问一下,下面两个针对XML节点的语句有区别吗:

    检查一个节点是否为空节点; 检查节点是否存在;

假设我有一个这样的 XML 文件:

<claim_export_xml>
<claim_export_xml_row>
    <claim_number>37423</claim_number>
    <total_submitted_charges>0</total_submitted_charges>
    <patient_control_no/>

    <current_onset_date>2009-06-07 00:00:00</current_onset_date>

我想检查“current_onset_date”节点是否存在,我使用了以下XSLT:

<xsl:for-each select="claim_export_xml_row ">
       <xsl:if test="claim_number =$mother_claim_no and /current_onset_date "> 

for-each 循环是我必须忍受的一些逻辑,以便循环工作。但是我在运行这个 XSLT 后实际上得到了错误的结果,上面的 xml 数据不会被我的 XSLT 抓取。但我认为使用“current_onset_date =‘‘”也不正确,因为它正在测试“current_onset_date 是否包含任何内容”。

谁能告诉我我的错误在哪里,并帮助我解决我在开头列出的问题,谢谢!

【问题讨论】:

【参考方案1】:

它应该可以工作,除了你有两个“和”并且你不需要在 current_onset_date 之前的前导 /。

如果您也想检查是否为空,可以使用:

<xsl:for-each select="claim_export_xml_row ">
   <xsl:if test="claim_number =$mother_claim_no and current_onset_date != ''">

这样做的原因是元素的字符串值是其中所有文本的连接,因此该表达式将仅选择存在current_onset_date 并包含非空字符串的行。如果你想排除只包含空格的元素,你可以这样写:

<xsl:for-each select="claim_export_xml_row ">
   <xsl:if test="claim_number =$mother_claim_no and normalize-space( current_onset_date ) != ''">

【讨论】:

一旦我去掉前导的 /,它会抱怨这是无效的 xpath 并且“and”是一个错字,对不起 删除 / 时收到的错误消息是什么?我测试了一个类似的构造,它运行良好。 它只是抱怨这个 XPath 无效,没有具体的推理。但是,我找到了一种解决方法,即使用 count(current_onset_date)!=0。您认为它进行了正确的测试吗? 是的,如果至少有一个具有该名称的标签,它将返回 true,如果没有,它将返回 false,但我仍然觉得奇怪的是,如果没有这种解决方法它就无法工作。跨度> @bizilop:我又试了一次,没有前导/,它成功了!我之前的尝试中一定有一些错别字。谢谢。你能帮我解决我最初的问题吗?【参考方案2】:

我想问一下,有没有 以下两者的区别 XML 节点的语句:

1.检查节点是否为空节点;

2.检查节点是否存在;

这些需要不同的表达式来测试:不存在的节点不是空节点:

current_onset_date 

这会选择当前节点的任何current_onset_date 子节点。它的布尔值是true(),当且仅当至少存在一个这样的孩子,而false()——否则。

current_onset_date/text()

这会选择当前节点的任何current_onset_date 子节点的任何文本节点子节点。如果没有,它的布尔值为false(),否则--true()

即使一个元素没有文本节点作为子节点,它仍然可能有一个非空字符串值,因为它可能有元素作为后代,并且其中一些元素后代可能有文本节点子节点。

current_onset_date[not(string(.))]

这会选择当前节点的任何current_onset_date 子节点,它们的字符串值为空字符串 ('')。这可能很适合“空元素”。

如果空是指字符串值为空或仅包含空格的元素,则此表达式:

current_onset_date[not(normalize-space())]

这会选择当前节点的任何 current_onset_date 子节点,它们的字符串值为空字符串 ('') 或仅包含空格的字符串。

谁能告诉我我的错误在哪里 是

在您的代码中:

<xsl:for-each select="claim_export_xml_row ">                            
   <xsl:if test="claim_number =$mother_claim_no 
                              and /current_onset_date ">      

test 属性中的表达式始终为false(),因为/current_onset_date 表示:(文档的)顶部元素名为“current_onset_date”,但在您的情况下,顶部元素名为claim_export_xml

你可能想要

claim_number =$mother_claim_no and current_onset_date 

如果你想让元素“非空”,那么:

    claim_number =$mother_claim_no 
   and 
    current_onset_date[normalize-space()]  

【讨论】:

以上是关于使用 XSLT 检查节点是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

c# XDocument:检查特定节点名称是不是存在,如果不添加

如何使用 XSLT 测试图像文件是不是存在?

在 XSLT 中,如何使用存在多个相同节点的 ID 从节点中选择一个值?

XSLT 仅在存在其他子节点属性时更改子节点

如何检查子节点是否不存在?

如何使用节点 js 检查“s3”/“azure”路径中是不是存在文件