【问题标题】:xpath concat function converts XML data into textxpath concat 函数将 XML 数据转换为文本
【发布时间】:2014-12-10 08:27:35
【问题描述】:

我正在应用 XPath 2.0 的 concat 函数来连接两个 xml 元素。它将它们连接起来,但以文本形式给出输出。我正在使用 XSLT 进行这种转换。

注意:我在网上研究过,concat函数默认将数据转换为文本格式,有什么办法可以绕过它,让连接后的数据仍然是XML格式。

输入 XML:

<?xml version="1.0"?><?xml-stylesheet type="text/xsl"?>

    <jsonObject>
       <alarm>
          <groups>1</groups>
          <typeKey>FIRE</typeKey>
          <longitude>65656</longitude>
          <victim>2</victim>
          <letitude>6566</letitude>
       </alarm>
       <alarm2>
       <data>Stewart</data>
      <data1>John</data1>
      </alarm2>
    </jsonObject>

输入 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

     <xsl:template match="//jsonObject/alarm">


        <Latitude><xsl:value-of select="letitude"/></Latitude>
        <Combine><xsl:value-of select="concat(//alarm,//alarm2) "/></Combine>


    </xsl:template>
    </xsl:stylesheet>

当前结果:

<?xml version="1.0" encoding="UTF-8"?>
   <Latitude>6566</Latitude>
<Combine>
      1
      FIRE
      65656
      2
      6566

   Stewart
  John
  </Combine>

预期结果:

<?xml version="1.0" encoding="UTF-8"?>
       <Latitude>6566</Latitude>
    <Combine>
              <groups>1</groups>
              <typeKey>FIRE</typeKey>
              <longitude>65656</longitude>
              <victim>2</victim>
              <letitude>6566</letitude>
              <data>Stewart</data>
          <data1>John</data1>
      </Combine>

【问题讨论】:

    标签: xml xslt xpath xslt-2.0


    【解决方案1】:

    如另一个答案中所述,您应该在此处使用xsl:copy-of

    但是,另一种方法是使用基于模板的解决方案,建立在 XSLT identity template 之上。

    试试这个 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes" />
    
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="alarm">
          <Latitude><xsl:value-of select="letitude"/></Latitude>
          <Combine>
            <xsl:apply-templates />
            <xsl:apply-templates select="../alarm2/*" />
          </Combine>
      </xsl:template>
    
      <xsl:template match="alarm2" />
    
    </xsl:stylesheet>
    

    因此,您可以通过将alarm 元素转换为Combine 元素并添加alarm2 的子元素来转换它。第二个模板匹配alarm2 本身以阻止它被输出两次。然后使用标识模板复制 XML 中的所有其他节点。

    【讨论】:

      【解决方案2】:

      concat() 只对文本进行操作。因此,它获取每个文本的值,然后将它们连接在一起。您不连接节点,而是需要复制每个节点:

      <Combine><xsl:copy-of select="//alarm/*"/><xsl:copy-of select="//alarm2/*"/></Combine>
      

      【讨论】:

      • 既然是2.0,你也可以使用&lt;xsl:copy-of select="*,../alarm2/*"/&gt;(上下文已经是alarm)。
      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2023-03-13
      • 2018-01-31
      • 2022-07-13
      • 2015-09-26
      • 1970-01-01
      相关资源
      最近更新 更多