如何在未绑定的 xml 结构中生成逗号分隔的字符串

Posted

技术标签:

【中文标题】如何在未绑定的 xml 结构中生成逗号分隔的字符串【英文标题】:How to generate comma separated string in to unbound xml structure 【发布时间】:2020-12-22 16:09:10 【问题描述】:

我的输入如下所示

<ns0:input>AZX1,P81,IKJU,RED</ns0:input>

我已经创建了带有未绑定元素的目标 xsd 来存储值

    <element name="Response">
    <complexType>
   <sequence>
    <element name="parameter" minOccurs="1" maxOccurs="unbounded">
     <complexType>
      <sequence>
       <element name="value" type="string"/>
      </sequence>
     </complexType>
    </element>
   </sequence>
  </complexType>
 </element>

所以我想要以下格式的输出。

<?xml version = '1.0' encoding = 'UTF-8'?>
<ns0:Response  xmlns:ns0="http://xmlns.oracle.com/CDM/Append/AppendBPELProcess">
   <ns0:parameter>
      <ns0:value>AZX1</ns0:value>
   </ns0:parameter>
   <ns0:parameter>
      <ns0:value>P81</ns0:value>
   </ns0:parameter>
   <ns0:parameter>
      <ns0:value>IKJU</ns0:value>
   </ns0:parameter>
   <ns0:parameter>
      <ns0:value>RED</ns0:value>
   </ns0:parameter>
</ns0:Response>

我尝试在 XSLT 中使用 oraext:create-nodeset-from-delimited-string 函数,但它给了我一个错误。有什么方法可以在 XSLT 中填充此输出或使用任何模板?

【问题讨论】:

您使用的是哪个 XSLT 引擎?贴出你目前写的代码。 我在我的 Jdevloper 工具上使用这个 XSLT。这是我在 xslt 中构建的 &lt;xsl:template match="/"&gt; &lt;ns0:Response&gt; &lt;ns0:parameter&gt; &lt;ns0:value&gt; &lt;xsl:value-of select="oraext:create-nodeset-from-delimited-string ('http://xmlns.oracle.com/CDM/Append/AppendBPELProcess', /ns0:process/ns0:input, ',' )"/&gt; &lt;/ns0:value&gt; &lt;/ns0:parameter&gt; &lt;/ns0:Response&gt; &lt;/xsl:template&gt; @Sebastien 如果它可以通过模板解决,那么您能否提供我该代码 您的 XSLT 引擎是否支持 XSLT 2.0?如果可以使用tokenize功能会简单很多。 没有。它只支持 xsl:stylesheet version="1.0" 【参考方案1】:

这是一种在 XSLT 1.0 中使用递归模板的方法。

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="http://xmlns.oracle.com/CDM/Append/AppendBPELProcess"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <ns0:Response>
      <xsl:apply-templates select="//ns0:input"/>
    </ns0:Response>
  </xsl:template>
  
  <xsl:template match="ns0:input">
    <xsl:call-template name="inputs">
      <xsl:with-param name="input" select="."/>
    </xsl:call-template>
  </xsl:template>
  
  <!-- Recursive template will call itself for all comma separated elements -->
  <xsl:template name="inputs">
    <xsl:param name="input"/>
    <xsl:choose>
      <xsl:when test="contains($input,',')">
        <ns0:parameter>
          <ns0:value><xsl:value-of select="substring-before($input,',')"/></ns0:value>
        </ns0:parameter>
        <xsl:call-template name="inputs">
          <xsl:with-param name="input" select="substring-after($input,',')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <ns0:parameter>
          <ns0:value><xsl:value-of select="$input"/></ns0:value>
        </ns0:parameter>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
</xsl:stylesheet>

在这里看到它的工作:https://xsltfiddle.liberty-development.net/a9HjZW/1

更新:排除第一个元素

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="http://xmlns.oracle.com/CDM/Append/AppendBPELProcess"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <ns0:Response>
      <xsl:apply-templates select="//ns0:input"/>
    </ns0:Response>
  </xsl:template>
  
  <xsl:template match="ns0:input">
    <xsl:call-template name="inputs">
      <xsl:with-param name="input" select="."/>
      <xsl:with-param name="pos" select="1"/>
    </xsl:call-template>
  </xsl:template>
  
  <!-- Recursive template will call itself for all comma separated elements -->
  <xsl:template name="inputs">
    <xsl:param name="input"/>
    <xsl:param name="pos"/>
    <xsl:choose>
      <xsl:when test="contains($input,',')">
        <xsl:if test="$pos>1">
            <ns0:parameter>
              <ns0:value><xsl:value-of select="substring-before($input,',')"/></ns0:value>
            </ns0:parameter>
        </xsl:if>
        <xsl:call-template name="inputs">
          <xsl:with-param name="input" select="substring-after($input,',')"/>
          <xsl:with-param name="pos" select="$pos+1"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="$pos>1">
            <ns0:parameter>
              <ns0:value><xsl:value-of select="$input"/></ns0:value>
            </ns0:parameter>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
</xsl:stylesheet>

在这里查看它的工作原理:https://xsltfiddle.liberty-development.net/a9HjZW/3

【讨论】:

最后一个值没有出现,输出显示为空。 '' @Harish 我修好了。 我对此的最终查询,如果我想始终排除第一个位置值 (AZX1) 并需要其余值。如何在同一个 XSLT 中做到这一点。 ' 你能帮我解决这个问题吗? @Harish 我更新了我的解决方案以排除第一个元素。 逗号分隔的值它作为例外工作。但是当测试给出一个字符串&lt;ns0:input&gt;AZX1&lt;/ns0:input&gt;然后输出应该是空的,因为我说第一个位置不需要。但结果是有价值的。

以上是关于如何在未绑定的 xml 结构中生成逗号分隔的字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何从数据库表中生成xml文件?

如何将逗号分隔的字符串转换为数组?

从逗号分隔的字符串 [XML/XSL] 创建选择下拉列表

使用SQL如何把用逗号等字符隔开的字符串转换成列表

如何让一个字符串(由多个小字符串,中间以逗号分隔开)转换成stringlist类

如何从 JQuery 中的逗号分隔值列表中绑定 <select>?