包含 CDATA

问题描述

我必须使用 XSLT 转换 xml 文件

我必须在输出获取输入文件文件的某些结构,预计 CDATA 元素上存在的某些元素会发生一些变化。

<soapenv:Envelope xmlns:aa="http://example.com"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <aa:importOrder>
         <aa:orderNumber>00501010000342</aa:orderNumber>
         <aa:data>
            <![CDATA[
                <?xml version="1.0" encoding="UTF-8"?>
                    <OrderImport xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
                        <OrderNumber>00501010000342</OrderNumber>
                        <Application>
                            <Student>
                                    <DataElement>
                                            <Name>age</Name>
                                            <Type>Int</Type>
                                            <Value>13</Value>
                                    </DataElement>
                                    <DataElement>
                                            <Name>firstName</Name>
                                            <Type>String</Type>
                                            <Value>taha</Value>
                                    </DataElement>
                            </Student>
                        </Application>
                    </OrderImport>
                ]]>
            </aa:data>
      </aa:importOrder>
   </soapenv:Body>
</soapenv:Envelope> 

我的预期输出应该是这样的:

<soapenv:Envelope xmlns:aa="http://example.com"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <aa:importOrder>
         <aa:orderNumber>00501010000342</aa:orderNumber>
         <aa:data>
            <![CDATA[
                <?xml version="1.0" encoding="UTF-8"?>
                    <OrderImport xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
                        <OrderNumber>00501010000342</OrderNumber>
                        <Application>
                            <Student>
                                    <DataElement>
                                            <Name>age</Name>
                                            <Type>Int</Type>
                                            **<Value>Other Value</Value>**
                                    </DataElement>
                                    <DataElement>
                                            <Name>firstName</Name>
                                            <Type>String</Type>
                                            **<Value>Other Value</Value>**
                                    </DataElement>
                            </Student>
                        </Application>
                    </OrderImport>
                ]]>
            </aa:data>
      </aa:importOrder>
   </soapenv:Body>
</soapenv:Envelope>

为此,我使用了这个 xsl 文件

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

<xsl:template match="DataElement">
    <p>
        <xsl:apply-template select="name"/>
    </p>
</xsl:template>

<xsl:template match="Name | Type">
    <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="Value">
    Other Value
</xsl:template>

但我没有得到预期的输出

提前致谢

解决方法

要解析 CDATA 中的内部 XML,您可以使用 parse-xml,然后通过更改元素值的模板推送节点,然后重新序列化并确保将 aa:data 定义为 CDATA 部分元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:aa="http://example.com"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" cdata-section-elements="aa:data"/>

  <xsl:template match="aa:data">
      <xsl:copy>
          <xsl:variable name="transformed">
              <xsl:apply-templates select="parse-xml(replace(.,'^\s+',''))/node()"/>
          </xsl:variable>
          <xsl:value-of select="serialize($transformed,map { 'method' : 'xml','omit-xml-declaration' : false() })"/>
      </xsl:copy>
  </xsl:template>
  
  <xsl:template match="Value" xpath-default-namespace="http://test.com">
      <xsl:copy>Other Value</xsl:copy>
  </xsl:template>

</xsl:stylesheet>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...