模板匹配打印匹配标记的所有内容

时间:2017-07-14 09:22:08

标签: xml xslt

为什么我在打印标签时会打印出来?我只是想进入那个节点,所以我不必总是输入路径?以下是XML示例:

           <?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="blablabla" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <CstmrCdtTrfInitn>
      <GrpHdr>
         <MsgId>35006</MsgId>
         <CreDtTm>2017-04-13T08:30:09</CreDtTm>
         <NbOfTxs>3</NbOfTxs>
         <CtrlSum>22000.00</CtrlSum>
         <InitgPty>
            <Nm>XXXXX</Nm>
            <Id>
               <OrgId>
                  <Othr>
                     <Id>0000010681</Id>
                  </Othr>
               </OrgId>
            </Id>
         </InitgPty>
      </GrpHdr>
      <PmtInf>
         <PmtInfId>35006_26011</PmtInfId>
         <PmtMtd>TRF</PmtMtd>
         <NbOfTxs>3</NbOfTxs>
         <CtrlSum>22000.00</CtrlSum>
         <PmtTpInf />
         <ReqdExctnDt>2017-04-13</ReqdExctnDt>
         <Dbtr>
            <Nm>WWWWWWW</Nm>
            <PstlAdr>
               <StrtNm>AAAAAA</StrtNm>
               <PstCd>BBBBBB</PstCd>
               <TwnNm>CCCCCC</TwnNm>
               <Ctry>PL</Ctry>
            </PstlAdr>
            <Id>
               <OrgId>
                  <Othr>
                     <Id>0000010681</Id>
                  </Othr>
               </OrgId>
            </Id>
         </Dbtr>
      </PmtInf>
   </CstmrCdtTrfInitn>
</Document>

以下是我想要收到的内容:

1.  XXXXX
2.  AAAAAA
3.  BBBBBB
4.  CCCCCC

我得到了:

350062017-04-13T08:30:09322000.00XXXXX0000010681
  1.
  WWWWWWW
  2.
  AAAAAA
  3.
  BBBBBB
  4.
  CCCCCC

使用此XLST:

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="blablabla" version="1.0">
   <xsl:output method="text" encoding="utf-8" />
   <xsl:strip-space elements="*" />
   <xsl:template match="doc:PmtInf">
      1.
      <xsl:value-of select="doc:Dbtr/doc:Nm" />
      2.
      <xsl:value-of select="doc:Dbtr/doc:PstlAdr/doc:StrtNm" />
      3.
      <xsl:value-of select="doc:Dbtr/doc:PstlAdr/doc:PstCd" />
      4.
      <xsl:value-of select="doc:Dbtr/doc:PstlAdr/doc:TwnNm" />
   </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

这是因为当处理器在XSLT中找不到匹配的模板时使用的built-in template rules

XML的处理由XSLT开始,寻找与文档节点匹配的模板(由/表示),并且因为您在XSLT中没有模板匹配,所以内置模板适用

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

这将简单地遍历节点,并查找匹配子节点的模板。

当它到达CstmrCdtTrfInitn时,您也没有匹配的模板,因此内置模板仍适用于选择其子项。您的模板匹配pmtInf但不匹配GrpHdr。对于GrpHdr元素,最终内置模板将到达文本节点,这些节点将被这些

匹配
<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

换句话说,内置模板输出它找到的任何文本节点,这就是你得到额外文本的原因。

你可以做的是添加一个匹配GrpHdr的模板并告诉XSLT不再进一步

<xsl:template match="doc:GrpHdr" />

或者你可以有一个匹配doc:CstmrCdtTrfInitn的模板,然后只选择你想要的子节点。

<xsl:template match="doc:CstmrCdtTrfInitn">
  <xsl:apply-templates select="doc:PmtInf" />
</xsl:template>

如果您根本不想依赖内置模板,或者您的XML中有其他元素即将发挥作用,您也可以尝试添加此模板,匹配文档节点,然后将straigt跳转到PmtInf节点。

 <xsl:template match="/">
    <xsl:apply-templates select="doc:Document/doc:CstmrCdtTrfInitn/doc:PmtInf" />
 </xsl:template>

例如,这应该会为您提供所需的结果

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="blablabla" version="1.0">
   <xsl:output method="text" encoding="utf-8" />
   <xsl:strip-space elements="*" />

   <xsl:template match="doc:GrpHdr" />

   <xsl:template match="doc:PmtInf">
      1. <xsl:value-of select="doc:Dbtr/doc:Nm" />
      2. <xsl:value-of select="doc:Dbtr/doc:PstlAdr/doc:StrtNm" />
      3. <xsl:value-of select="doc:Dbtr/doc:PstlAdr/doc:PstCd" />
      4. <xsl:value-of select="doc:Dbtr/doc:PstlAdr/doc:TwnNm" />
   </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:-1)

更改

      <xsl:value-of select="doc:Dbtr/doc:Nm" />

      <xsl:value-of select="ancestor-or-self::Document/CstmrCdtTrfInitn/GrpHdr/InitgPty/Nm" />

ancestor-or-self让您拥有从xml文档的顶部节点中选择的能力