2012-10-04 69 views
2

我有一个输入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> 

任何建议将不胜感激。

+1

要点澄清......空''元素不是“根元素”。 “根”是指文档的最外层。 ''元素有一个父亲'',所以他们不能成为根。 – LarsH

+0

哦,也许你的意思是“叶元素”,也就是没有孩子的元素。 (“叶节点”是图论和CS中的一个通用术语,但不是特别的XML,不像“根节点”。) – LarsH

回答

1

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

<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> 
+0

感谢一大堆,这似乎为我工作....非常感谢。 – Abhi

5

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

<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> 

当这个变换所提供的XML文档应用:

<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> 

有用,正确的结果产生

<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> 

说明

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

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

+0

+1,很好的解决方案。为了完整性,我们可能会指出''模板将会吞下具有属性的元素(但不包含子元素)。也许这就是OP想要的,如果“空”意味着“没有孩子”。无论如何,这与给定的输入数据无关。但是,如果我们决定不想吞下具有属性的元素:'' – LarsH

+0

@LarsH,是的,是正确的。该解决方案只针对提供的XML文档。谢谢。 –