草庐IT

xml - XSLT 将元素从源复制到 CDATA 部分

coder 2024-06-25 原文

我正在将一个简单的 SOAP XML 消息转换为一个更扩展的 SOAP XML 消息。我几乎可以正常工作了,但我无法解决最后两个问题。我的问题是:

  1. 元素之后的所有元素都应该在 CDATA 部分中。我尝试使用“cdata-section-elements”,但无法正常工作。
  2. 元素应该是这样的

我的源 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <test>
      <element1>123</element1>
      <element2>123</element2>
    </test>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" exclude-result-prefixes="fn xs SOAP-ENV">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

<!-- Special rule to match the document root only -->
<xsl:template match="/*">
    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
        <xsl:namespace name="a" select="'http://www.w3.org/2005/08/addressing'"/>
        <xsl:apply-templates select="@*|node()"/>
    </s:Envelope>
</xsl:template>

<!-- Expand soap header -->
<xsl:template match="SOAP-ENV:Header">
    <xsl:element name="s:{local-name()}" namespace="http://www.w3.org/2003/05/soap-envelope">
        <xsl:element name="a:Action" namespace="http://www.w3.org/2005/08/addressing">
            <xsl:attribute name="s:mustUnderstand" namespace="http://www.w3.org/2003/05/soap-envelope">1</xsl:attribute>
            <xsl:text>http://www.ortec.com/CAIS/IApplicationIntegrationService/SendMessage</xsl:text>
        </xsl:element>
    </xsl:element>
</xsl:template>

<!-- Change soap body -->
<xsl:template match="SOAP-ENV:Body">
    <xsl:element name="s:{local-name()}" namespace="http://www.w3.org/2003/05/soap-envelope">
        <xsl:element name="cais:SendMessage" namespace="http://www.ortec.com/CAIS">
            <xsl:element name="cais:message" namespace="http://www.ortec.com/CAIS">
                <!-- copy the rest -->
                <xsl:apply-templates select="child::node()"/>
            </xsl:element>
            <xsl:element name="cais:commandName" namespace="http://www.ortec.com/CAIS">Import</xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:template>

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

我现在收到此 XSLT 的错误输出:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.ortec.com/CAIS/IApplicationIntegrationService/SendMessage</a:Action>
  </s:Header>
  <s:Body>
    <cais:SendMessage xmlns:cais="http://www.ortec.com/CAIS">
      <cais:message>
        <test xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
          <element1>123</element1>
          <element2>123</element2>
        </test>
      </cais:message>
      <cais:commandName>Import</cais:commandName>
    </cais:SendMessage>
  </s:Body>
</s:Envelope>

我想要的输出:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.ortec.com/CAIS/IApplicationIntegrationService/SendMessage</a:Action>
  </s:Header>
  <s:Body>
    <cais:SendMessage xmlns:cais="http://www.ortec.com/CAIS">
      <cais:message>
        <![CDATA[
        <test>
          <element1>123</element1>
          <element2>123</element2>
        </test>
        ]]>
      </cais:message>
      <cais:commandName>Import</cais:commandName>
    </cais:SendMessage>
  </s:Body>
</s:Envelope>

最佳答案

以下是否可行?

<xsl:template match="SOAP-ENV:Body">
    <xsl:element name="s:{local-name()}" namespace="http://www.w3.org/2003/05/soap-envelope">
        <xsl:element name="cais:SendMessage" namespace="http://www.ortec.com/CAIS">
            <xsl:element name="cais:message" namespace="http://www.ortec.com/CAIS">
                <!-- copy the rest -->
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                <xsl:apply-templates select="child::node()"/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </xsl:element>
            <xsl:element name="cais:commandName" namespace="http://www.ortec.com/CAIS">Import</xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:template>

当我以这种方式修改 XSLT 并在您的样本输入上运行它时,我得到:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header><a:Action s:mustUnderstand="1" xmlns:a="http://www.w3.org/2005/08/addressing">http://www.ortec.com/CAIS/IApplicationIntegrationService/SendMessage</a:Action></s:Header>
  <s:Body><cais:SendMessage xmlns:cais="http://www.ortec.com/CAIS"><cais:message>
  <![CDATA[
    <test xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <element1>123</element1>
      <element2>123</element2>
    </test>
  ]]>
  </cais:message>
  <cais:commandName>Import</cais:commandName></cais:SendMessage></s:Body>
</s:Envelope>

namespace 声明仍然存在,但这并不重要。

如果你真的想去掉 <test> 上的命名空间声明,您可以将您的身份模板替换为:

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

  <xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:apply-templates select="@* | node()" />
    </xsl:element>
  </xsl:template>

我已经验证这似乎有效。

另外,如果您提前知道元素的前缀和名称,则无需使用 xsl:elementnamespace属性。如果您在 xsl:spreadsheet 中声明 namespace 元素:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                   xmlns:fn="http://www.w3.org/2005/xpath-functions" 
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:s="http://www.w3.org/2003/05/soap-envelope"
                   xmlns:cais="http://www.ortec.com/CAIS"
                   exclude-result-prefixes="fn xs SOAP-ENV cais">

那么你可以这样做:

<xsl:template match="SOAP-ENV:Body">
    <xsl:element name="s:{local-name()}">
        <cais:SendMessage>
            <cais:message>
                <!-- copy the rest -->
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                <xsl:apply-templates select="child::node()"/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </cais:message>
            <cais:commandName>Import</cais:commandName>
        </cais:SendMessage>
    </xsl:element>
</xsl:template>

关于xml - XSLT 将元素从源复制到 CDATA 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14851215/

有关xml - XSLT 将元素从源复制到 CDATA 部分的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  3. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  4. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  5. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  6. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  7. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

  8. ruby - 使用 Nokogiri 和 Ruby 命名元素 "text" - 2

    我在尝试使用Nokogiri构建XML文档时遇到了一个小问题。我想将我的元素之一称为“文本”(请参阅​​下面粘贴代码的最底部)。通常,要创建一个新元素,我会执行类似以下的操作xml.text--但它似乎是.text是Nokogiri已经用来做其他事情的方法。因此,当我写这行时xml.textNokogiri没有创建名为的新元素但只是写了意味着成为元素内容的文本。我怎样才能让Nokogiri实际制作一个名为的元素??builder=Nokogiri::XML::Builder.newdo|xml|xml.TEI("xmlns"=>"http://www.tei-c.org/ns/1.0"

  9. ruby - 在两个 ActiveRecord 类之间合并/复制属性的好方法? - 2

    之前有人问过这个问题,我发现了以下clip关于如何一次设置一个类对象的所有属性,但由于批量分配保护,这在Rails中是不可能的。(例如,您不能Object.attributes={})有没有一种很好的方法可以将一个类的属性合并到另一个类中?object1.attributes=object2.attributes.inject({}){|h,(k,v)|h[k]=vifObjectModel.column_names.include?(k);h}谢谢。 最佳答案 利用assign_attributes使用:without_prote

  10. ruby - 在 factory_girl 中有没有办法获取 attributes_for 并为同一个实例元素创建? - 2

    如果我想使用“create”构建策略创建和实例,然后想使用“attributes_for”构建策略进行验证,是否可以这样做?如果我在工厂中使用序列?在Machinistgem中有可能吗? 最佳答案 不太确定我是否完全理解。而且我不是机械师的用户。但听起来您只是想做这样的事情。@attributes=FactoryGirl.attributes_for(:my_object)my_object=MyObject.create(@attributes)my_object.some_property.should==@attributes

随机推荐