Forcing Empty CDATA Elements

别等时光非礼了梦想. 提交于 2020-01-06 01:52:06

问题


I was questioned if i could transform an xml by using xsl (1.0) but with keeping the CDATA elements even if there is no content in it. As xsl beginner i am a little bit overwhelmed by that question...

here is a simple sample.

what i have

<AMOUNT/>

what i want

<AMOUNT><![CDATA[]]></AMOUNT>
  • is there a way to force empty cdata segments with no content?
  • Is there a way to do it for all elements in the file?
  • Is there a way to do it just for the ones in the cdata-section-elements?

(have a look at the AMOUNT element)

here is my sample 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>

here is my sample 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>

here is the actual output

<?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>

(these are just cutouts of the real files)


回答1:


To force an empty CDATA section you can do this:

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

If you don't know whether the value is empty or not, you can use a conditional:

<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>

Which you can then wrap in a template:

<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>

Which you then use like so:

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

But again, there should be no need for empty CDATA sections--honestly there is no need for any CDATA sections anywhere in the document at all! You see how it greatly complicates document production and consumption and increases document size (in your case) even though the XML Infoset of the document is exactly the same.

Also, remember you can't use CDATA sections inside attribute values, so make sure you never use cdata-value-of or empty-cdata to generate an attribute value or your XML will probably not be well-formed!



来源:https://stackoverflow.com/questions/15585507/forcing-empty-cdata-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!