xml 使用 XSLT 检查节点是否存在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4694480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:29:44  来源:igfitidea点击:

Check if a node exists using XSLT

xmlxslt

提问by Kevin

To begin with, I would like to ask, is there a difference between the following two statements for XML nodes:

首先,我想问一下,对于XML节点,以下两种说法是否有区别:

  1. check whether a node is an empty node;
  2. check whether a node exists or not;
  1. 检查节点是否为空节点;
  2. 检查节点是否存在;

Suppose I have an XML file like this:

假设我有一个这样的 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>

and I want to check whether the "current_onset_date" node exists or not, I used the following XSLT:

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

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

The for-each loop is some logic that I have to bear with in order for the loop to work. But I actuall got wrong result after running this XSLT, the above xml data won't be grabbed by my XSLT. But I don't think using "current_onset_date =‘‘ ” is correct either, since it is testing for "whether current_onset_date contains nothing".

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

Could anybody tell me where my mistake is and also help me with my question listed in the beginning, thanks!

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

采纳答案by biziclop

It should work except that you've got two "and"'s and you don't need the leading / before current_onset_date.

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

If you want to check for emptiness as well, you can use:

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

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

The reason this works is that the string value of an element is the concatenation of all the text inside it, so this expression will only select rows where current_onset_dateexists and contains a non-empty string. If you want to exclude elements that contain nothing but whitespace, you can write:

这样做的原因是元素的字符串值是其中所有文本的串联,因此该表达式将仅选择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 ) != ''">

回答by Dimitre Novatchev

I would like to ask, is there a difference between the following two statements for XML nodes:

1.check whether a node is an empty node;

2.check whether a node exists or not;

我想问一下,对于XML节点,下面两种说法有区别吗:

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

2.检查节点是否存在;

These require different expressions to test for: a node that doesn't exist is not an empty node:

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

current_onset_date 

this selects any current_onset_datechildren of the current node. Its boolean value is true()if and only if at least one such child exists, and false()-- otherwise.

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

current_onset_date/text()

this selects any text node children of any current_onset_datechildren of the current node. If there are none, its boolean value is false(), otherwise -- true(),

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

Even if an element doesn't have text-nodes as children, it still may have a non-empty string value, because it may have elements as descendents and some of these element-descendents may have text-node children.

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

current_onset_date[not(string(.))]

this selects any current_onset_datechildren of the current node, that have the empty string ('') as their string value. This might qualify well for "empty element".

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

If by empty you mean an element whose string-value is either empty or white-space-only, then this expression:

如果空是指一个字符串值为空或只有空格的元素,那么这个表达式:

current_onset_date[not(normalize-space())]

this selects any current_onset_datechildren of the current node, that have the empty string ('') or an white-space-only string as their string value.

这将选择current_onset_date当前节点的任何子节点,这些子节点具有空字符串 ('') 或仅包含空格的字符串作为其字符串值。

Could anybody tell me where my mistake is

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

In your code:

在您的代码中:

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

the expression in the testattribute is always false()because /current_onset_datemeans: the top element (of the document) named "current_onset_date" , but the top element in your case is named claim_export_xml

test属性中的表达式总是false()因为/current_onset_date意味着:(文档的)顶部元素名为 "current_onset_date" ,但在您的情况下顶部元素名为 claim_export_xml

You probably want:

你可能想要

claim_number =$mother_claim_no and current_onset_date 

And if you want the element to be "non-empty", then:

如果您希望元素为“非空”,则:

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