强制清空CDATA元素

时间:2013-03-23 10:07:03

标签: xml xslt xslt-1.0 cdata

我被问到是否可以使用xsl(1.0)转换xml,但即使没有内容也要保留CDATA元素。作为xsl初学者,我对这个问题有点不知所措......

这是一个简单的样本。

我有什么

<AMOUNT/>

我想要什么

<AMOUNT><![CDATA[]]></AMOUNT>
  • 有没有办法强制没有内容的空cdata段?
  • 有没有办法为文件中的所有元素执行此操作?
  • 有没有办法只针对 cdata-section-elements 中的那些?

(看看AMOUNT元素)

这是我的样本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 个答案:

答案 0 :(得分: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部分 - 说实话,文档中的任何地方都不需要任何CDATA部分!您会看到它如何使文档生成和使用大大复杂化并增加文档大小(在您的情况下),即使文档的XML Infoset完全相同。

另外,请记住,您不能在属性值中使用CDATA部分,因此请确保永远不要使用cdata-value-ofempty-cdata来生成属性值,否则您的XML可能不会格式正确!