使用XSLT进行XML转换

时间:2015-04-08 04:45:25

标签: xml xslt

我想转换我的XML文档,但不确定是否可以使用XSLT获得所需的输出。 以下是我的XML代码:

    <GetInvoiceList>
    <Request>
    <Case>
    <id>Case_1</id>
    <CaseID>Hi</CaseID>
    </Case>
    <BillStatusCode>
    <BillStatusCode>type description</BillStatusCode>
    <typecode>1</typecode>
    </BillStatusCode>
    <EBillProcessStatusCode>
    <EBillProcessStatusCode>type description</EBillProcessStatusCode>
    <typecode>2</typecode>
    </EBillProcessStatusCode>
    </Request>
    </GetInvoiceList>

我想把它转换成这个:

   <GetInvoiceList>
   <Request>
   <Case id="Case_1">
   <CaseID>Hi</CaseID>
   </Case>
   <BillStatusCode typecode="1">type description</BillStatusCode> 
   <EBillProcessStatusCode typecode="2">type description</EBillProcessStatusCode>
   </Request>
   </GetInvoiceList>

是否可以获得所需的输出? 非常感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

如果我理解正确,撤消你创建的混乱的“通用解决方案”将做两件事:

  1. idtypecode元素转换为其父元素的属性;

  2. 消除名称与其父元素名称相同的任何元素,并将其子节点(示例中的文本节点)复制到父元素。

  3. 这转换为:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="*">
        <xsl:copy>
            <xsl:for-each select="id | typecode">
                <xsl:attribute name="{name()}">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:for-each>
            <xsl:apply-templates select="node()[not(self::id or self::typecode)]"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="*[name(.) = name(..)]">
        <xsl:apply-templates/>
    </xsl:template>
    
    </xsl:stylesheet>
    

答案 1 :(得分:0)

试试!!!,现在我已根据元素位置更改了编码。 如果您更改输入中的元素位置,这对您没有帮助。

此致 巴拉

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
   <xsl:strip-space elements="*"/>

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

  <xsl:template match="*" mode="all">
    <xsl:choose>
      <xsl:when test="(count(ancestor::*) = 3 and count(preceding::*) = 0)
                      or (count(ancestor::*) = 3 and count(preceding::*) > 1 and count(preceding-sibling::*) = 1)">
      </xsl:when>
      <xsl:when test="count(ancestor::*) = 3 and count(preceding-sibling::*) = 0">
        <xsl:apply-templates mode="all"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy>
          <xsl:choose>
            <xsl:when test="count(ancestor::*) = 2 and count(preceding-sibling::*) = 0">
              <xsl:attribute name="{*[1]/name()}" select="*[1]"/>
            </xsl:when>
            <xsl:when test="count(ancestor::*) = 2 and count(preceding-sibling::*) != 0">
              <xsl:attribute name="{*[2]/name()}" select="*[2]"/>
            </xsl:when>
          </xsl:choose>
          <xsl:apply-templates mode="all"/>
        </xsl:copy>        
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>