XSLT验证:for-each给出错误“不允许空序列作为xsl:analyze-string的@select属性”

时间:2014-02-04 13:15:26

标签: xml xslt

我正在尝试验证在XML消息中重复的日期格式。当我在模板中只有一个日期时,我得到了同样的“空字符串”错误。我能够让这个模板起作用。但是当我添加一个“for-each”构造来解释可能在XML消息中重复的日期时,我得到错误“不允许空序列作为xsl:analyze-string的@select属性”。除了我不明白为什么我只是通过添加“for-each”而得到这个错误的事实,我不确定为什么验证代码认为有一个空序列。虽然可能缺少日期(我认为我第一次修复了,当不使用for-each构造时),我的测试消息确实有我试图测试的日期。我在网站上阅读了其他一些答案,但要么我不明白如何应用修复程序,要么我不知道建议的修复程序是否能解决我的问题(我不是程序员)。

有人可以帮我修复此代码,以便我可以测试这个重复的日期吗?

消息的结构是

<VXU_V04.ORDER> One or more may be present, not a required group; I’m calling this “OrderGroup”
<RXA> Required; only one RXA Segment per OrderGroup allowed
<RXA.3> Required; only one RXA.3 field per RXA Segment allowed
<TS.1> is a sub-components of RXA.3

以下是示例消息的相关部分

 <VXU_V04.ORDER>
    <ORC>
      <ORC.1>RE</ORC.1>
      <ORC.3>
        <EI.1>197023</EI.1>
        <EI.2>DCS</EI.2>
      </ORC.3>
      <ORC.10>
        <XCN.2>
          <FN.1>Clerk</FN.1>
        </XCN.2>
        <XCN.3>Myron</XCN.3>
      </ORC.10>
      <ORC.17>
        <CE.1>DCS</CE.1>
        <CE.2>Dabig Clinical System</CE.2>
        <CE.3>StateIIS</CE.3>
      </ORC.17>
    </ORC>
    <RXA>
      <RXA.1>0</RXA.1>
      <RXA.2>1</RXA.2>
      <RXA.3>
        <TS.1>20090415132511</TS.1>
      </RXA.3>
      <RXA.4>
        <TS.1>20090415132511</TS.1>
      </RXA.4>
      <RXA.5>
        <CE.1>31</CE.1>
        <CE.2>Hep B Peds NOS</CE.2>
        <CE.3>CVX</CE.3>
      </RXA.5>
      <RXA.6>999</RXA.6>
      <RXA.9>
        <CE.1>01</CE.1>
        <CE.2>historical record</CE.2>
        <CE.3>NIP0001</CE.3>
      </RXA.9>
    </RXA>
  </VXU_V04.ORDER>
  <VXU_V04.ORDER>
    <ORC>
      <ORC.1>RE</ORC.1>
      <ORC.3>
        <EI.1>197027</EI.1>
        <EI.2>DCS</EI.2>
      </ORC.3>
      <ORC.10>
        <XCN.2>
          <FN.1>Clerk</FN.1>
        </XCN.2>
        <XCN.3>Myron</XCN.3>
      </ORC.10>
      <ORC.12>
        <XCN.2>
          <FN.1>Pediatric</FN.1>
        </XCN.2>
        <XCN.3>MARY</XCN.3>
        <XCN.10>L</XCN.10>
        <XCN.21>MD</XCN.21>
      </ORC.12>
    </ORC>
    <RXA>
      <RXA.1>0</RXA.1>
      <RXA.2>1</RXA.2>
      <RXA.3>
        <TS.1>20090531132511</TS.1>
      </RXA.3>
      <RXA.4>
        <TS.1>20090531132511</TS.1>
      </RXA.4>
      <RXA.5>
        <CE.1>48</CE.1>
        <CE.2>HIB PRP-T</CE.2>
        <CE.3>CVX</CE.3>
      </RXA.5>
      <RXA.6>999</RXA.6>
      <RXA.9>
        <CE.1>00</CE.1>
        <CE.2>new Immunization record</CE.2>
        <CE.3>NIP0001</CE.3>
      </RXA.9>
      <RXA.10>
        <XCN.2>
          <FN.1>Sticker</FN.1>
        </XCN.2>
        <XCN.3>Nurse</XCN.3>
      </RXA.10>
      <RXA.11>
        <LA2.4>
          <HD.1>DCS_DC</HD.1>
        </LA2.4>
      </RXA.11>
      <RXA.15>33k2a</RXA.15>
      <RXA.17>
        <CE.1>PMC</CE.1>
        <CE.2>sanofi</CE.2>
        <CE.3>MVX</CE.3>
      </RXA.17>
    </RXA>
    <RXR>
      <RXR.1>
        <CE.1>C28161</CE.1>
        <CE.2>IM</CE.2>
        <CE.3>NCIT</CE.3>
        <CE.4>IM</CE.4>
        <CE.5>IM</CE.5>
        <CE.6>HL70162</CE.6>
      </RXR.1>
    </RXR>
  </VXU_V04.ORDER>
  <VXU_V04.ORDER>
    <ORC>
      <ORC.1>RE</ORC.1>
      <ORC.3>
        <EI.1>197028</EI.1>
        <EI.2>DCS</EI.2>
      </ORC.3>
      <ORC.10>
        <XCN.2>
          <FN.1>Clerk</FN.1>
        </XCN.2>
        <XCN.3>Myron</XCN.3>
      </ORC.10>
      <ORC.12>
        <XCN.2>
          <FN.1>Pediatric</FN.1>
        </XCN.2>
        <XCN.3>MARY</XCN.3>
        <XCN.10>L</XCN.10>
        <XCN.21>MD</XCN.21>
      </ORC.12>
    </ORC>
    <RXA>
      <RXA.1>0</RXA.1>
      <RXA.2>1</RXA.2>
      <RXA.3>
        <TS.1>20090531132511</TS.1>
      </RXA.3>
      <RXA.4>
        <TS.1>20090531132511</TS.1>
      </RXA.4>
      <RXA.5>
        <CE.1>110</CE.1>
        <CE.2>DTAP-Hep B-IPV</CE.2>
        <CE.3>CVX</CE.3>
      </RXA.5>
      <RXA.6>999</RXA.6>
      <RXA.9>
        <CE.1>00</CE.1>
        <CE.2>new immunization record</CE.2>
        <CE.3>NIP0001</CE.3>
      </RXA.9>
      <RXA.10>
        <XCN.2>
          <FN.1>Sticker</FN.1>
        </XCN.2>
        <XCN.3>Nurse</XCN.3>
      </RXA.10>
      <RXA.11>
        <LA2.4>
          <HD.1>DCS_DC</HD.1>
        </LA2.4>
      </RXA.11>
      <RXA.15>xy3939</RXA.15>
      <RXA.17>
        <CE.1>SKB</CE.1>
        <CE.2>GSK</CE.2>
        <CE.3>MVX</CE.3>
      </RXA.17>
    </RXA>
    <RXR>
      <RXR.1>
        <CE.1>IM</CE.1>
        <CE.2>IM</CE.2>
        <CE.3>HL70162</CE.3>
        <CE.4>C28161</CE.4>
        <CE.5>IM</CE.5>
        <CE.6>NCIT</CE.6>
      </RXR.1>
    </RXR>
  </VXU_V04.ORDER>

这是我的验证模板。我尝试了一些不同的东西,比如在每个“analyze-string”函数之前使用“for-each”语句。我尝试在TS1Field上添加一个计数,但是当我尝试将计数检查合并到这里时,我一直收到语法错误:。

我认为这可能是我遇到的类似问题,模板无法识别我的子组件(TS1Field)。我在这个网站上发布了一个关于它的问题,得到了一个很好的答案,修复了另一个验证模板中的另一个问但是,当我在这里尝试相同的事情时,它不起作用。

(顺便说一句,我知道我在这里有一个不同领域的描述 - 患者死亡日期 - 但这是来自我用作此基础的模板。我还没有到处更新这些消息。)

<xsl:stylesheet version="2.0" xmlns:a="urn:hl7-org:v2xml" xmlns:dil="http://www.aegis.net/msg/filter/jaxb/rule" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!--      
             Must be VALUED AND 
             Must not repeat
         -->
    <xsl:variable name="OrderGroup" select="/a:VXU_V04/a:VXU_V04.ORDER"/>
    <xsl:variable name="RXASegment" select="/a:VXU_V04/a:VXU_V04.ORDER/a:RXA"/>
    <xsl:variable name="RXA3Field" select="/a:VXU_V04/a:VXU_V04.ORDER/a:RXA/a:RXA.3"/>
    <xsl:variable name="TS1Field" select="/a:VXU_V04/a:VXU_V04.ORDER/a:RXA/a:TS.1"/>
    <xsl:template match="/">
        <dil:filterruleresult>
             <xsl:choose>
                 <xsl:when test= "count($OrderGroup)= 0">
                    <dil:message type="info">VXU Order Group not found.</dil:message>
                 </xsl:when>
             </xsl:choose>
             <xsl:for-each select="$OrderGroup">
                     <xsl:choose>
                       <xsl:when test="count(a:RXA)= 0">  
                          <dil:message type="error">When Order Group present, RXA Segment is required.</dil:message>
                       </xsl:when>
                       <xsl:when test="count(a:RXA)> 1">  
                        <dil:message type="error">Only one Pharmacy/Treatment Administration Segment (RXA) allowed per Order Group.</dil:message>
                       </xsl:when>
                       <xsl:otherwise>
                          <xsl:for-each select="a:RXA">
                             <xsl:choose>
                                 <xsl:when test="count(a:RXA.3)= 0">
                                <dil:message type="error">RXA-3 Date/Time Start of Administration not found but is required.</dil:message>
                                 </xsl:when> 
                                 <xsl:when test="count(a:RXA.3)> 1">
                                <dil:message type="error">Only one Date/Time Start of Administration (RXA-3) allowed per Order Segment.</dil:message>
                                 </xsl:when> 
                                 <xsl:when test="count(a:RXA.3)= 1">
                                     <dil:message type="info">Valid value of '<xsl:value-of select="./a:RXA.3"/>' found for Administered Amount (RXA-6).</dil:message>
                                 </xsl:when>
                               </xsl:choose>
                          </xsl:for-each>     
                                   <xsl:for-each select="a:RXA/a:RXA.3">
                                            <xsl:analyze-string regex="([&quot;|'])(.*?)\1" select="$TS1Field">
                                <xsl:matching-substring>
                                    <dil:message type="error">Patient Death Date and Time (PID-29) '<xsl:value-of select="$TS1Field"/>' found in message, but contains invalid apostrophes or quotes within the value text.</dil:message>
                                </xsl:matching-substring>
                                <xsl:non-matching-substring>
                                    <dil:message type="info">Patient Death Date and Time (PID-29) '<xsl:value-of select="$TS1Field"/>' found in message.  If any validation errors are found, they will follow this message. </dil:message>
                                </xsl:non-matching-substring>
                            </xsl:analyze-string>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,1,4) !=''">
                                    <xsl:analyze-string regex="^(19|20)\d{{2}}$" select="substring($TS1Field,1,4)">
                                        <xsl:non-matching-substring>
                                            <dil:message type="error">Patient Death Date and Time (PID-29) value for year not a valid year as required.  Valid years have century of 19 or 20.  Found value '<xsl:value-of select="substring($TS1Field,1,4)"/>' in message.</dil:message>
                                        </xsl:non-matching-substring>
                                    </xsl:analyze-string>
                                </xsl:when>
                            </xsl:choose>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,5,2) !=''">
                                    <xsl:analyze-string regex="0[1-9]|1[0-2]" select="substring($TS1Field,5,2)">
                                        <xsl:non-matching-substring>
                                            <dil:message type="error">Patient Death Date and Time (PID-29) value for month not a valid month as required.  Valid months are 01-12.  Found value '<xsl:value-of select="substring($TS1Field,5,2)"/>' in message.</dil:message>
                                        </xsl:non-matching-substring>
                                    </xsl:analyze-string>
                                </xsl:when>
                            </xsl:choose>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,7,2) !=''">
                                    <xsl:analyze-string regex="0[1-9]|1[0-9]|2[0-9]|3[0-1]" select="substring($TS1Field,7,2)">
                                        <xsl:non-matching-substring>
                                            <dil:message type="error">Patient Death Date and Time (PID-29) value for day not a valid day value as required.  Valid days are 01-31.  Found value '<xsl:value-of select="substring($TS1Field,7,2)"/>' in message.</dil:message>
                                        </xsl:non-matching-substring>
                                    </xsl:analyze-string>
                                </xsl:when>
                            </xsl:choose>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,9,2) !=''">
                                    <xsl:analyze-string regex="0[0-9]|1[0-9]|2[0-3]" select="substring($TS1Field,9,2)">
                                        <xsl:non-matching-substring>
                                            <dil:message type="error">Patient Death Date and Time (PID-29) value for hour not a valid hour value as required.  Valid values are 00-23.  Found value '<xsl:value-of select="substring($TS1Field,9,2)"/>' in message.</dil:message>
                                        </xsl:non-matching-substring>
                                    </xsl:analyze-string>
                                </xsl:when>
                            </xsl:choose>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,11,2) !=''">
                                    <xsl:analyze-string regex="0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]" select="substring($TS1Field,11,2)">
                                        <xsl:non-matching-substring>
                                            <dil:message type="error">Patient Death Date and Time (PID-29) value for hour not a valid for minute not a valid minute value as required.  Valid values are 00-59.  Found value '<xsl:value-of select="substring($TS1Field,11,2)"/>' in message.</dil:message>
                                        </xsl:non-matching-substring>
                                    </xsl:analyze-string>
                                </xsl:when>
                            </xsl:choose>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,13,2) !=''">
                                    <xsl:analyze-string regex="0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]" select="substring($TS1Field,13,2)">
                                        <xsl:non-matching-substring>
                                            <dil:message type="error">Patient Death Date and Time (PID-29) value for seconds not a valid seconds value as required.  Valid values are 00-59.  Found value '<xsl:value-of select="substring($TS1Field,13,2)"/>' in message.</dil:message>
                                        </xsl:non-matching-substring>
                                    </xsl:analyze-string>
                                </xsl:when>
                            </xsl:choose>
                   </xsl:for-each>         
                   <xsl:for-each select="a:RXA/a:RXA.3">
                            <xsl:choose>
                                <xsl:when test="substring($TS1Field,15,1) !=''">
                                    <dil:message type="error">Patient Death Date and Time (PID-29) value is too long.  Valid format is CCYYMMDD.  Found value '<xsl:value-of select="$TS1Field"/>' in message.</dil:message>
                                </xsl:when>
                                            </xsl:choose>
                                   </xsl:for-each>  
                       </xsl:otherwise>
                      </xsl:choose> 
             </xsl:for-each>      
        </dil:filterruleresult>
    </xsl:template>
</xsl:stylesheet>

任何建议都将不胜感激。

谢谢!

1 个答案:

答案 0 :(得分:3)

你宣布了

<xsl:variable name="TS1Field" select="/a:VXU_V04/a:VXU_V04.ORDER/a:RXA/a:TS.1"/>

但没有TS.1元素是RXA的直接子元素(它们都在RXA.3RXA.4内),因此变量设置为空序列,因此

<xsl:analyze-string regex="([&quot;|'])(.*?)\1" select="$TS1Field">

会抱怨您所看到的错误。但是因为你在里面

<xsl:for-each select="a:RXA/a:RXA.3">

分析a:TS1代替$TS1Field(即您当前正在查看的特定TS1内的RXA.3)可能更有意义。