xml属性和元素更改-xslt

时间:2016-03-31 00:31:14

标签: xslt

我的XML输入是:

<TestResponse>
<TestData1/>
<TestData2/>
<TestFinance>
 <Name>TestW</Name>
<id/>
<overDueCounts>
       **<overDueCount days="30">0</overDueCount>**
       <overDueCount days="45">0</overDueCount>
       <overDueCount days="45">0</overDueCo
</overDueCounts>
</TestFinance>
<TestNonFinance>
<Name>TestR</Name>
<id/>
<overDueCounts>
       <overDueCount days="30">0</overDueCount>
       <overDueCount days="45">0</overDueCount>
       <overDueCount days="45">0</overDueCo
</overDueCounts>
</TestNonFinance>
<TestData3/>
</TestResponse>

预期输出是仅选择<TestFinance> and <TestNonFinance>元素及其子元素组合在<Aggregate>父元素中。此外,<TestFinance> and <TestNonFinance>中的所有属性都应转换为子元素。我加粗了这些元素和属性。

预期产出:

  <Aggregate>
    <TestFinance>
    <Name>TestW</Name>
    <id/>
     <overDueCounts>
               **<overDueCount>
               <days>30</days>
               <count>0</count>
               </overDueCount>**
               <overDueCount>
               <days>45</days>
               <count>0</count>
               </overDueCount>
               <overDueCount>
               <days>45</days>
               <count>0</count>
               </overDueCount>
    </overDueCounts>
    </TestFinance>
    <TestNonFinance>
         <overDueCounts>
               <overDueCount> 
               <days>30</days>
               <countdue>0</countdue>
                 </overDueCount>
               <overDueCount>
                  <days>45</days>
               <countdue>0</countdue>
                 </overDueCount>
               <overDueCount>
                  <days>30</days>
               <countdue>0</countdue>
                 </overDueCount>
    </overDueCounts>
    </TestNonFinance>
    </Aggregate>

我写了如下的XSLT,

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:regexp="http://exslt.org/regular-expressions" exclude-result-prefixes="regexp">
    <xsl:output method="xml"/>
    <!-- Template to copy the node without namespaces -->
    <xsl:template match="*" mode="copy-no-namespaces">
        <xsl:element name="{local-name()}">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()" mode="copy-no-namespaces"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="comment()| processing-instruction()" mode="copy-no-namespaces">
        <xsl:copy/>
    </xsl:template>
    <xsl:variable name="TestFinance">
        <xsl:apply-templates select="./*[local-name() = 'TestResponse']/*[local-name() = 'TestFinance']" mode="copy-no-namespaces"/>
    </xsl:variable>
        <xsl:variable name="TestNonFinance">
        <xsl:apply-templates select="./*[local-name() = 'TestResponse']/*[local-name() = 'TestNonFinance']" mode="copy-no-namespaces"/>
    </xsl:variable>
    <xsl:template match="/">
        <Aggregate>
            <xsl:copy-of select="$TestFinance"/>
              <xsl:copy-of select="$TestNonFinance"/>
        </Aggregate>
    </xsl:template>
    </xsl:stylesheet>

但是结果如下所示。请注意,我可以选择<TestFinance> and <TestNonFinance>并将它们合并在一起。但是无法将属性转换为子元素。

    <Aggregate>
    <TestFinance>
    <Name>TestW</Name>
    <id/>
     <overDueCounts>
               <overDueCount days="30">0</overDueCount>
               <overDueCount days="45">0</overDueCount>
               <overDueCount days="45">0</overDueCo
    </overDueCounts>
    </TestFinance>
    <TestNonFinance>
    <Name>TestR</Name>
    <id/>
     <overDueCounts>
               <overDueCount days="30">0</overDueCount>
               <overDueCount days="45">0</overDueCount>
               <overDueCount days="45">0</overDueCo
    </overDueCounts>
    </TestNonFinance>
</Aggregate>

请帮助将属性转换为子元素并生成预期输出。

1 个答案:

答案 0 :(得分:0)

即使我不明白你为什么使用copy-no-namespaces变量。

添加两个模板应该会有所帮助:

overDueCount的特殊处理:

 <xsl:template match="overDueCount" mode="copy-no-namespaces">
      <!-- create an element overDueCount -->
      <xsl:element name="{local-name()}">
           <!-- "call" template  to create a element for each attribute -->
          <xsl:apply-templates select="@*" mode="attrtotag"/>
           <!--crate a element count  with value from current node -->
          <count><xsl:value-of select="."/></count>
           <!-- call templates for all child elements -->
          <xsl:apply-templates select="*" mode="copy-no-namespaces"/>
      </xsl:element>
  </xsl:template>

从属性创建标记的模板:

  <xsl:template match="@*" mode="attrtotag">
      <!-- create a new element with name of current attribute -->
      <xsl:element name="{local-name()}">
          <!-- get the content(value) form the attribute -->
          <xsl:value-of select="."/>
      </xsl:element>
  </xsl:template>

输出:

<overDueCounts>
   **<overDueCount><days>30</days><count>0</count></overDueCount>**
   <overDueCount><days>45</days><count>0</count></overDueCount>
   <overDueCount><days>45</days><count>0</count></overDueCount>
</overDueCounts>