仅剥离空根元素

时间:2012-10-04 04:49:10

标签: xml xslt strip

我有一个输入XML,它看起来像这样,并希望使用XSL转换,如下所示输出所需的输出。我一直在浏览博客但是找不到任何关于如何删除匹配根元素而不是子节点的空标签的相关性。

<?xml version="1.0" encoding="UTF-8"?>
<objects xmlns="urn:sobject.partner.soap.sforce.com">
  <Revenue__c/>
  <Revenue__c/>
  <Revenue__c/>
  <Revenue__c>
    <Sales_Org_ID__c>IV</Sales_Org_ID__c>
    <Branch_ID__c>1</Branch_ID__c>
    <Branch_Name__c>TEST</Branch_Name__c>
    <Therapy_Code__c>TEST</Therapy_Code__c>
    <Therapy_Name__c>TEST</Therapy_Name__c>
    <Therapy_Class_Code__c>TEST</Therapy_Class_Code__c>
    <Therapy_Class_Name__c>TEST</Therapy_Class_Name__c>
    <Payor_Type_Name__c>TEST</Payor_Type_Name__c>
    <Calendar_Year_Number__c>2011</Calendar_Year_Number__c>
    <Month_Revenue_Amount__c>100.01</Month_Revenue_Amount__c>
    <Payor_ID__c>TEST</Payor_ID__c>
    <Payor_Name__c/>
    <Payor_Type_Code__c>TEST</Payor_Type_Code__c>
    <MDM_Account_EID__c>66600001</MDM_Account_EID__c>
    <MDM_Physician_EID__c>99900001</MDM_Physician_EID__c>
    <Account__c>001a000001APU5OAAX</Account__c>
    <Contact__c>003a000001RL1EFAA1</Contact__c>
    <Revenue_ID__c>41</Revenue_ID__c>
    <Calendar_Year_Month__c>01</Calendar_Year_Month__c>
  </Revenue__c>
</objects>

这正是我想要的:

<?xml version="1.0" encoding="UTF-8"?>
<objects xmlns="urn:sobject.partner.soap.sforce.com">
  <Revenue__c>
    <Sales_Org_ID__c>IV</Sales_Org_ID__c>
    <Branch_ID__c>1</Branch_ID__c>
    <Branch_Name__c>TEST</Branch_Name__c>
    <Therapy_Code__c>TEST</Therapy_Code__c>
    <Therapy_Name__c>TEST</Therapy_Name__c>
    <Therapy_Class_Code__c>TEST</Therapy_Class_Code__c>
    <Therapy_Class_Name__c>TEST</Therapy_Class_Name__c>
    <Payor_Type_Name__c>TEST</Payor_Type_Name__c>
    <Calendar_Year_Number__c>2011</Calendar_Year_Number__c>
    <Month_Revenue_Amount__c>100.01</Month_Revenue_Amount__c>
    <Payor_ID__c>TEST</Payor_ID__c>
    <Payor_Name__c/>
    <Payor_Type_Code__c>TEST</Payor_Type_Code__c>
    <MDM_Account_EID__c>66600001</MDM_Account_EID__c>
    <MDM_Physician_EID__c>99900001</MDM_Physician_EID__c>
    <Account__c>001a000001APU5OAAX</Account__c>
    <Contact__c>003a000001RL1EFAA1</Contact__c>
    <Revenue_ID__c>41</Revenue_ID__c>
    <Calendar_Year_Month__c>01</Calendar_Year_Month__c>
  </Revenue__c>
</objects>

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:5)

这可能是最简单/最短的解决方案,同时完全是“推送风格”,并且是最具可扩展性和可维护性的 - 没有硬编码的元素名称,没有文字结果元素,没有名称空间,没有{{1 }}

xsl:copy-of

在提供的XML文档上应用此转换时:

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

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>
 <xsl:template match="/*/*[not(node())]"/>
</xsl:stylesheet>

产生了想要的正确结果

<objects xmlns="urn:sobject.partner.soap.sforce.com">
    <Revenue__c/>
    <Revenue__c/>
    <Revenue__c/>
    <Revenue__c>
        <Sales_Org_ID__c>IV</Sales_Org_ID__c>
        <Branch_ID__c>1</Branch_ID__c>
        <Branch_Name__c>TEST</Branch_Name__c>
        <Therapy_Code__c>TEST</Therapy_Code__c>
        <Therapy_Name__c>TEST</Therapy_Name__c>
        <Therapy_Class_Code__c>TEST</Therapy_Class_Code__c>
        <Therapy_Class_Name__c>TEST</Therapy_Class_Name__c>
        <Payor_Type_Name__c>TEST</Payor_Type_Name__c>
        <Calendar_Year_Number__c>2011</Calendar_Year_Number__c>
        <Month_Revenue_Amount__c>100.01</Month_Revenue_Amount__c>
        <Payor_ID__c>TEST</Payor_ID__c>
        <Payor_Name__c/>
        <Payor_Type_Code__c>TEST</Payor_Type_Code__c>
        <MDM_Account_EID__c>66600001</MDM_Account_EID__c>
        <MDM_Physician_EID__c>99900001</MDM_Physician_EID__c>
        <Account__c>001a000001APU5OAAX</Account__c>
        <Contact__c>003a000001RL1EFAA1</Contact__c>
        <Revenue_ID__c>41</Revenue_ID__c>
        <Calendar_Year_Month__c>01</Calendar_Year_Month__c>
    </Revenue__c>
</objects>

<强>解释

  1. 身份规则“按原样”复制选择执行此模板的任何节点。

  2. 有一个模板会覆盖顶级元素的子元素且没有子元素的任何元素的标识模板。该模板没有主体(不产生任何输出),有效地“删除”了匹配的节点。

答案 1 :(得分:1)

这应该这样做 - 它只将apply-templates用于带子项的Revenue节点,然后copy-of复制非空的Revenue树。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:x="urn:sobject.partner.soap.sforce.com"
                exclude-result-prefixes="x">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

  <xsl:template match="/x:objects">
    <objects xmlns="urn:sobject.partner.soap.sforce.com">
      <xsl:apply-templates select="x:Revenue__c[*]" />
    </objects>
  </xsl:template>

  <xsl:template match="x:Revenue__c">
    <xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>

输出

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="urn:sobject.partner.soap.sforce.com">
  <Revenue__c>
    <Sales_Org_ID__c>IV</Sales_Org_ID__c>
    <Branch_ID__c>1</Branch_ID__c>
    <Branch_Name__c>TEST</Branch_Name__c>
    <Therapy_Code__c>TEST</Therapy_Code__c>
    <Therapy_Name__c>TEST</Therapy_Name__c>
    <Therapy_Class_Code__c>TEST</Therapy_Class_Code__c>
    <Therapy_Class_Name__c>TEST</Therapy_Class_Name__c>
    <Payor_Type_Name__c>TEST</Payor_Type_Name__c>
    <Calendar_Year_Number__c>2011</Calendar_Year_Number__c>
    <Month_Revenue_Amount__c>100.01</Month_Revenue_Amount__c>
    <Payor_ID__c>TEST</Payor_ID__c>
    <Payor_Name__c />
    <Payor_Type_Code__c>TEST</Payor_Type_Code__c>
    <MDM_Account_EID__c>66600001</MDM_Account_EID__c>
    <MDM_Physician_EID__c>99900001</MDM_Physician_EID__c>
    <Account__c>001a000001APU5OAAX</Account__c>
    <Contact__c>003a000001RL1EFAA1</Contact__c>
    <Revenue_ID__c>41</Revenue_ID__c>
    <Calendar_Year_Month__c>01</Calendar_Year_Month__c>
  </Revenue__c>
</objects>

修改 - 可以简化:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:x="urn:sobject.partner.soap.sforce.com"
                exclude-result-prefixes="x">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

  <xsl:template match="/x:objects">
    <objects xmlns="urn:sobject.partner.soap.sforce.com">
      <xsl:copy-of select="x:Revenue__c[*]" />
    </objects>
  </xsl:template>
</xsl:stylesheet>