2012-04-05 142 views
3

我有一個大的XSD,有看起來像這樣的內容:如何將這些嵌入式元素轉換爲父元素的屬性?

<xs:element name="ProgramName" type="xs:string" minOccurs="0"> 
    <xs:annotation> 
    <xs:documentation>PN</xs:documentation> 
    </xs:annotation> 
</xs:element> 
<xs:element name="TestItem" type="xs:string" minOccurs="0"> 
    <xs:annotation> 
    <xs:documentation>TA</xs:documentation> 
    </xs:annotation> 
</xs:element> 

我想給<documentation>元素收縮到祖父母元素的屬性,就像這樣:

<xs:element name="ProgramName" type="xs:string" minOccurs="0" code="PN"> 
</xs:element> 
<xs:element name="TestItem" type="xs:string" minOccurs="0" code="TA"> 
</xs:element> 

怎麼可能這是用XSLT完成的嗎?或者,是否有比XSLT更好的(閱讀:更簡單)的方法?

生成的XSD將與XSD.EXE一起用於創建C#類,用於序列化和反序列化目的。原始XSD不能以這種方式使用,因爲XSD.EXE會刪除所有註釋元素,因此這些註釋中包含的信息將丟失。

回答

2

這是我會怎麼做它:

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

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

    <xsl:template match="*[xs:annotation]"> 
    <xsl:copy> 
     <xsl:attribute name="code"><xsl:value-of select="xs:annotation/xs:documentation"/></xsl:attribute> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy>  
    </xsl:template> 

    <xsl:template match="xs:annotation"/>  

</xsl:stylesheet> 
+0

謝謝。現在我只需要弄清楚如何針對原始XSD執行它。 :P正如你可能已經猜到的那樣,我對XSLT沒有任何經驗,儘管我知道它的目的是什麼。我向那些比我更開明的XSLT大師鞠躬。 – 2012-04-05 21:37:35

+0

@RobertHarvey - 我絕對沒有上師,但我很高興能夠幫到你。 – 2012-04-05 21:52:53

+1

@ ??? - 爲什麼downvote? – 2012-04-11 16:08:38

0

這只是另一個答案:)

<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="node()[local-name()='element']"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()[local-name()!='annotation']"/> 
     <xsl:for-each select="node()[local-name()='annotation']/node()[local-name()='documentation']"> 
     <xsl:attribute name="code"> 
      <xsl:value-of select="."/> 
     </xsl:attribute> 
     </xsl:for-each> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

確實使用XSLT重新排列節點,而不是做的很好的想法手動:)我總是使用XSLT ..
我們甚至可以使用它來從XSD生成示例XML ..如果XSD與可承受的大小:)

+1

我建議你嘗試你的XSLT對付一個具有一些全局類型的XSD;一個簡單的,如在SO上發佈的[here](http://stackoverflow.com/questions/10043414/how-to-define-a-specific-number-in-xsd)。你會發現你的行爲不起作用,至少與@ DevNull相比......我會讓你弄清楚爲什麼......那麼也許你可以更新你的帖子。 – 2012-04-06 19:29:00

+0

@PetruGardea,它適用於OP的問題。如果元素內部定義了複雜的類型,那麼我的代碼不起作用我知道那是因爲我忽略了''內的所有ELEMENT節點..而是if他們在其中定義複雜類型,並將其用作應該工作的元素的類型。 – 2012-04-07 09:22:01

+0

@PetruGardea,我會立即更新我的答案..以使其工作,例如你已經提到。 – 2012-04-07 09:22:17