XML和XSLT保留CDATA [英] XML and XSLT keep CDATA

查看:55
本文介绍了XML和XSLT保留CDATA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个项目,其中包括在xml上应用一些xslt。

I am working on a project which includes applying some xslt on xml.

我的输入xml在任何xml节点中都包含 CDATA。

My Input xml contains "CDATA" in any of the xml node.

现在我想要的是如果输入中应该包含 CDATA

Now what i want is it should keep "CDATA" if it has in input

我尝试了很多解决方案,例如disable-output -转义和cdata-section-elements等...
,但是我发现它们都不适合我的需求。

I tried many solutions like disable-output-escaping and cdata-section-elements etc... but i found none of them are appropriate for my requirement.

所以,我有什么办法吗可以做到??如果输入xml节点具有cdata,则应在输出中提供它,如果输入xml节点不具有cdata,则不应在输出中提供它。

So, is there any way i can do it?? If input xml nodes has cdata then it should give it in output if input xml nodes doesnt have cdata then it should not give it in output.

我有一个名为的节点,其中包含

I have node called which contains cdata and another node at some diff location which doesnt contain cdata..

<Address>
<Location>
<Code>912</Code>
<Value>10301</Value>
</Location>
<Name><![CDATA[E&S]]></Name>
<CompanyName><![CDATA[E&S]]></CompanyName>
<AddressLine3>dummy address</AddressLine3>
<City>dummy city</City>
<State>dummy state</State>
<PostalCode>dummy postal code</PostalCode>
<Country>dummy country</Country>
</Address>
<Nodes>
<Node>
<Type>CTU</Type>
<Text><![CDATA[dummy text & dummy Text.]]></Text>
</Node>
</Nodes>

不固定,只有预定义的节点将包含它可以出现在任何地方的cdata

It is not fixed that only pre-defined nodes will contain cdata it can come anywhere

推荐答案

XSLT使用的XPath数据模型不允许区分任何CDATA节-其中的任何一个都表示为(一部分)文本节点。因此,不能完全单独使用XSLT或XPath来实现CDATA保留。

The XPath data model that XSLT uses doesn't allow to distinguish any CDATA sections -- any of these are represented just as (part of) a text node. So CDATA preservation cannot be achieved with XSLT or XPath alone in full generality. It could be achieved with a DOM based approach.

如果在转换的输出中,具有特定名称的元素的文本节点需要CDATA部分,而对于其他,则可以在XSLT中完成,在< xsl:output> cdata-section-elements 属性c>声明。

If in the output of the transformation CDATA sections are needed for the text nodes of elements with specific names, and not needed for others, then this is possible to accomplish in XSLT specifying a cdata-section-elements attribute in the <xsl:output> declaration.

下面是一个简短的示例

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"
 cdata-section-elements="a b c d e"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

此转换应用于以下XML文档时:

<Record>
    <a>10:30</a>
    <b>20:30</b>
    <c>10:60</c>
    <d>1:15</d>
    <e>1:03</e>
</Record>

产生了所需的正确结果

<Record>
   <a><![CDATA[10:30]]></a>
   <b><![CDATA[20:30]]></b>
   <c><![CDATA[10:60]]></c>
   <d><![CDATA[1:15]]></d>
   <e><![CDATA[1:03]]></e>
</Record>

如果事先不知道元素名称集,则可以使用生成另一个样式表的样式表,该样式表应最终应用于XML文档以产生所需的结果

<xsl:stylesheet version="1.0" xmlns:x="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xxx="xxx">
 <xsl:namespace-alias stylesheet-prefix="xxx" result-prefix="xsl"/>
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kElemByName" match="*[text()[normalize-space()]]" use="name()"/>

 <xsl:variable name="vDistinctNamedElems" select=
 "//*[generate-id()=generate-id(key('kElemByName',name())[1])]"/>

 <xsl:variable name="vDistinctNames">
  <xsl:for-each select="$vDistinctNamedElems">
   <xsl:value-of select="concat(name(), ' ')"/>
  </xsl:for-each>
 </xsl:variable>

 <xsl:template match="node()|@*">
  <xxx:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xxx:output omit-xml-declaration="yes" indent="yes"
       cdata-section-elements="{$vDistinctNames}"/>
    <xxx:strip-space elements="*"/>

    <xxx:template match="node()|@*">
     <xxx:copy>
       <xxx:apply-templates select="node()|@*"/>
     </xxx:copy>
    </xxx:template>
  </xxx:stylesheet>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一XML文档时(上面),结果是另一个XSLT样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:x="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
   <xsl:output omit-xml-declaration="yes" indent="yes" cdata-section-elements="a b c d e "/>
   <xsl:strip-space elements="*"/>
   <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

在此样式表中, cdata-section-elements 属性是动态生成的(使用Muenchian方法进行分组)。

In this stylesheet all the element names in the cdata-section-elements attribute, are dynamically generated (using the Muenchian method for grouping).

当我们最终将生成的XSLT样式表应用于同一XML文档,我们得到所需的结果

<Record>
   <a><![CDATA[10:30]]></a>
   <b><![CDATA[20:30]]></b>
   <c><![CDATA[10:60]]></c>
   <d><![CDATA[1:15]]></d>
   <e><![CDATA[1:03]]></e>
</Record>

说明


  1. 使用XSLT指令 xsl:namespace-alias

孟买分组 确定所有不同的元素名称。

Muenchian grouping to determine all distinct element names.

这篇关于XML和XSLT保留CDATA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆