2013-03-23 58 views
1

我被质疑是否可以通过使用xsl(1.0)来转换xml,但即使没有内容,也要保留CDATA元素。由于xsl初学者我有点不知所措,这个问题...强制清空CDATA元素

这里是一个简单的例子。

我有什么

<AMOUNT/> 

我想要什么

<AMOUNT><![CDATA[]]></AMOUNT> 
  • 有没有办法迫使空CDATA段没有内容?
  • 有没有办法为文件中的所有元素做到这一点?
  • 有没有办法只为cdata-section-elements

(看看量元素)

这里是我的示例XML

<?xml version="1.0" encoding="iso-8859-1" ?> 
    <Artikel> 
     <Temp> 
      <Zeile>107</Zeile> 
      <Artikelzubehoerdaten> 
       <Artikelzubehoerdaten> 
        <ZubehoerID>18</ZubehoerID> 
        <Mandant>88</Mandant> 
        <UrsprungsArt>1</UrsprungsArt> 
        <Ursprungsnummer>99100091</Ursprungsnummer> 
        <UrsprungsAuspraegungID>0</UrsprungsAuspraegungID> 
        <ZubehoerArt>1</ZubehoerArt> 
        <Zubehoernummer>00500041</Zubehoernummer> 
        <ZubehoerAuspraegungID>0</ZubehoerAuspraegungID> 
        <Automatisch>0</Automatisch> 
        <Mengenberechnung>1</Mengenberechnung> 
        <MengenFaktor>1.0000</MengenFaktor> 
        <Basismengeneinheit>Stk</Basismengeneinheit> 
        <Preisgrundlagen>2</Preisgrundlagen> 
        <ManuellerPreis>0.0000</ManuellerPreis> 
        <PreislisteID>0</PreislisteID> 
        <Timestamp>AAAAAAAEbVw=</Timestamp> 
        <Gruppendaten/> 
       </Artikelzubehoerdaten> 
       <Artikelzubehoerdaten> 
        <ZubehoerID>19</ZubehoerID> 
        <Mandant>88</Mandant> 
        <UrsprungsArt>1</UrsprungsArt> 
        <Ursprungsnummer>99100091</Ursprungsnummer> 
        <UrsprungsAuspraegungID>0</UrsprungsAuspraegungID> 
        <ZubehoerArt>2</ZubehoerArt> 
        <Zubehoernummer>100</Zubehoernummer> 
        <Automatisch>0</Automatisch> 
        <Mengenberechnung>0</Mengenberechnung> 
        <MengenFaktor>0.0000</MengenFaktor> 
        <Preisgrundlagen>0</Preisgrundlagen> 
        <ManuellerPreis>0.0000</ManuellerPreis> 
        <PreislisteID>0</PreislisteID> 
        <Timestamp>AAAAAAAEbWA=</Timestamp> 
        <Gruppendaten> 
         <ZubehoerID>1</ZubehoerID> 
         <Mandant>88</Mandant> 
         <UrsprungsArt>2</UrsprungsArt> 
         <Ursprungsnummer>100</Ursprungsnummer> 
         <ZubehoerArt>1</ZubehoerArt> 
         <Zubehoernummer>10300003</Zubehoernummer> 
         <ZubehoerAuspraegungID>0</ZubehoerAuspraegungID> 
         <Automatisch>0</Automatisch> 
         <Mengenberechnung>2</Mengenberechnung> 
         <MengenFaktor>1.0000</MengenFaktor> 
         <Basismengeneinheit>Stk</Basismengeneinheit> 
         <Preisgrundlagen>2</Preisgrundlagen> 
         <ManuellerPreis>0.0000</ManuellerPreis> 
         <PreislisteID>0</PreislisteID> 
         <Timestamp>AAAAAAABuBI=</Timestamp> 
        </Gruppendaten> 
        <Gruppendaten> 
         <ZubehoerID>2</ZubehoerID> 
         <Mandant>88</Mandant> 
         <UrsprungsArt>2</UrsprungsArt> 
         <Ursprungsnummer>100</Ursprungsnummer> 
         <ZubehoerArt>1</ZubehoerArt> 
         <Zubehoernummer>10300001</Zubehoernummer> 
         <ZubehoerAuspraegungID>0</ZubehoerAuspraegungID> 
         <Automatisch>0</Automatisch> 
         <Mengenberechnung>2</Mengenberechnung> 
         <MengenFaktor>1.0000</MengenFaktor> 
         <Basismengeneinheit>Stk</Basismengeneinheit> 
         <Preisgrundlagen>2</Preisgrundlagen> 
         <ManuellerPreis>0.0000</ManuellerPreis> 
         <PreislisteID>0</PreislisteID> 
         <Timestamp>AAAAAAABuBM=</Timestamp> 
        </Gruppendaten> 
        <Gruppendaten> 
         <ZubehoerID>3</ZubehoerID> 
         <Mandant>88</Mandant> 
         <UrsprungsArt>2</UrsprungsArt> 
         <Ursprungsnummer>100</Ursprungsnummer> 
         <ZubehoerArt>1</ZubehoerArt> 
         <Zubehoernummer>10300002</Zubehoernummer> 
         <ZubehoerAuspraegungID>0</ZubehoerAuspraegungID> 
         <Automatisch>0</Automatisch> 
         <Mengenberechnung>2</Mengenberechnung> 
         <MengenFaktor>1.0000</MengenFaktor> 
         <Basismengeneinheit>Stk</Basismengeneinheit> 
         <Preisgrundlagen>2</Preisgrundlagen> 
         <ManuellerPreis>0.0000</ManuellerPreis> 
         <PreislisteID>0</PreislisteID> 
         <Timestamp>AAAAAAABuBQ=</Timestamp> 
        </Gruppendaten> 
       </Artikelzubehoerdaten> 
       <Artikelzubehoerdaten> 
        <ZubehoerID>21</ZubehoerID> 
        <Mandant>88</Mandant> 
        <UrsprungsArt>1</UrsprungsArt> 
        <Ursprungsnummer>99100091</Ursprungsnummer> 
        <UrsprungsAuspraegungID>0</UrsprungsAuspraegungID> 
        <ZubehoerArt>2</ZubehoerArt> 
        <Zubehoernummer>200</Zubehoernummer> 
        <Automatisch>0</Automatisch> 
        <Mengenberechnung>0</Mengenberechnung> 
        <MengenFaktor>0.0000</MengenFaktor> 
        <Preisgrundlagen>0</Preisgrundlagen> 
        <ManuellerPreis>0.0000</ManuellerPreis> 
        <PreislisteID>0</PreislisteID> 
        <Timestamp>AAAAAAAEk3U=</Timestamp> 
        <Gruppendaten> 
         <ZubehoerID>20</ZubehoerID> 
         <Mandant>88</Mandant> 
         <UrsprungsArt>2</UrsprungsArt> 
         <Ursprungsnummer>200</Ursprungsnummer> 
         <ZubehoerArt>1</ZubehoerArt> 
         <Zubehoernummer>00200050</Zubehoernummer> 
         <ZubehoerAuspraegungID>0</ZubehoerAuspraegungID> 
         <Automatisch>0</Automatisch> 
         <Mengenberechnung>1</Mengenberechnung> 
         <MengenFaktor>1.0000</MengenFaktor> 
         <Basismengeneinheit>Stk</Basismengeneinheit> 
         <Preisgrundlagen>2</Preisgrundlagen> 
         <ManuellerPreis>0.0000</ManuellerPreis> 
         <PreislisteID>0</PreislisteID> 
         <Timestamp>AAAAAAAEk3I=</Timestamp> 
        </Gruppendaten> 
       </Artikelzubehoerdaten> 
      </Artikelzubehoerdaten> 
     </Temp> 
    </Artikel> 

这里是我的示例XSL

<?xml version="1.0" encoding="iso-8859-1" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes" cdata-section-elements ="ARTICLE AUTO AMOUNT GROUP_NUMBER"/> 
    <xsl:template match="/"> 
     <ARTICLE_LIST> 
      <xsl:for-each select="Artikel/Temp">  
       <ARTICLE> 
        <CROSS_SELLINGS> 
         <xsl:for-each select="Artikelzubehoerdaten/Artikelzubehoerdaten[ZubehoerArt=1]"> 
          <CROSS_SELLING> 
           <ARTICLE><xsl:value-of select="Zubehoernummer"/></ARTICLE> 
           <AUTO><xsl:value-of select="Automatisch"/></AUTO> 
           <GROUP_NUMBER></GROUP_NUMBER> 
           <AMOUNT><xsl:value-of select="MengenFaktor"/></AMOUNT> 
          </CROSS_SELLING> 
         </xsl:for-each> 
         <xsl:for-each select="Artikelzubehoerdaten/Artikelzubehoerdaten[ZubehoerArt=2]"> 
          <xsl:for-each select="Gruppendaten"> 
           <CROSS_SELLING> 
            <ARTICLE><xsl:value-of select="Zubehoernummer"/></ARTICLE> 
            <AUTO><xsl:value-of select="Automatisch"/></AUTO> 
            <GROUP_NUMBER><xsl:value-of select="Ursprungsnummer"/></GROUP_NUMBER> 
            <AMOUNT></AMOUNT> 
           </CROSS_SELLING> 
          </xsl:for-each> 
         </xsl:for-each> 
        </CROSS_SELLINGS> 
       </ARTICLE> 
      </xsl:for-each> 
     </ARTICLE_LIST> 
    </xsl:template> 

</xsl:stylesheet> 

这里实际产出

<?xml version="1.0" encoding="iso-8859-1"?> 
<ARTICLE_LIST> 
    <ARTICLE> 
     <CROSS_SELLINGS> 
     <CROSS_SELLING> 
      <ARTICLE><![CDATA[00500041]]></ARTICLE> 
      <AUTO><![CDATA[0]]></AUTO> 
      <GROUP_NUMBER/> 
      <AMOUNT><![CDATA[1.0000]]></AMOUNT> 
     </CROSS_SELLING> 
     <CROSS_SELLING> 
      <ARTICLE><![CDATA[10300003]]></ARTICLE> 
      <AUTO><![CDATA[0]]></AUTO> 
      <GROUP_NUMBER><![CDATA[100]]></GROUP_NUMBER> 
      <AMOUNT/> 
     </CROSS_SELLING> 
     <CROSS_SELLING> 
      <ARTICLE><![CDATA[10300001]]></ARTICLE> 
      <AUTO><![CDATA[0]]></AUTO> 
      <GROUP_NUMBER><![CDATA[100]]></GROUP_NUMBER> 
      <AMOUNT/> 
     </CROSS_SELLING> 
     <CROSS_SELLING> 
      <ARTICLE><![CDATA[10300002]]></ARTICLE> 
      <AUTO><![CDATA[0]]></AUTO> 
      <GROUP_NUMBER><![CDATA[100]]></GROUP_NUMBER> 
      <AMOUNT/> 
     </CROSS_SELLING> 
     <CROSS_SELLING> 
      <ARTICLE><![CDATA[00200050]]></ARTICLE> 
      <AUTO><![CDATA[0]]></AUTO> 
      <GROUP_NUMBER><![CDATA[200]]></GROUP_NUMBER> 
      <AMOUNT/> 
     </CROSS_SELLING> 
     </CROSS_SELLINGS> 
    </ARTICLE> 
</ARTICLE_LIST> 

(这些只是真实文件的切口)

+1

为什么你会想要这样做?为什么要使用CDATA部分? – 2013-03-23 11:15:19

+0

我认为“另一边的人”不会解析它,因为他们应该(可能是文本或我不知道的东西),我的老板无法说服他们正确解析它,他们总是需要所有标签上的cdata,即使它是空的...所以我在这里:( – Belial09 2013-03-23 11:25:17

+1

我以前见过这种情况,在源数据中强制CDATA段意味着在另一侧读取的程序不必转换为HTML编码实体,如“<" ">”,它是纯粹的懒惰并使数据文件非常复杂,有人可能会认为采用像CSV这样简单的数据格式会更好......与这些人一起玩,他们会找到其他方法让他们的问题成为你的:-) – 2013-03-23 15:25:30

回答

4

要强制空CDATA部分,你可以这样做:

<xsl:template name="empty-cdata"> 
    <xsl:text disable-output-escaping="yes"><![CDATA[]]></xsl:text> 
</xsl:template> 

如果你不知道该值是否空或不空,你可以使用条件:

<xsl:choose> 
    <xsl:when test="string-length(.)"> 
    <xsl:value-of select="."/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:call-template name="empty-cdata"/> 
    </xsl:otherwise> 
</xsl:choose> 

然后你可以包装在模板中:

<xsl:template name="cdata-value-of"> 
    <xsl:param name="value"/> 
    <xsl:choose> 
    <xsl:when test="string-length($value)"> 
     <!-- let cdata-section-elements take care of wrapping 
      in a CDATA section if needed. Otherwise you will 
      need to do string-replacement of ']]>' yourself. --> 
     <xsl:value-of select="$value"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:call-template name="empty-cdata"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

,你再使用像这样:

<AMOUNT> 
    <xsl:call-template name="cdata-value-of"> 
    <xsl:with-param name="value" select="MengenFaktor"/> 
    </xsl:call-template> 
</AMOUNT> 

但同样,应该不需要空CDATA部分 --honestly没有必要对任何CDATA部分文档中任何地方根本!您会发现,即使文档的XML Infoset完全相同,文档的生成和消耗也会大大增加,并增加文档大小(就您的情况而言)。

此外,请记住,您不能使用属性值中的CDATA部分,因此请确保您从不使用cdata-value-ofempty-cdata来生成属性值,否则您的XML可能不会完好形成!

+1

谢谢你,它的工作,我需要改变' '到'的 \t \t的!< [CDATA []] > \t' – Belial09 2013-03-23 19:23:09

+0

奇怪的是,在我的处理器(libxslt/libxml2)上只有我的版本有效。还有另一个原因,我想这是一个坏主意!禁用输出转义在自己的危险! – 2013-03-23 20:26:26