2012-03-05 162 views
1

正在嘗試使用XSLT 1.0XSLT:我想基於使用XSLT 1.0

源XML扁平化基礎上的子元素名稱的XML元素的子元素的名字拼合XML元素:

<Contact> 
    <ContactPurpose> 
    <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
    </ContactPurpose> 
    <ContactPurpose> 
    <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
    </ContactPurpose> 
</Contact> 

應變換爲下面的XML:

<Contact> 
    <ContactPurpose>O</ContactPurpose> 
    <ContactPurpose>Call</ContactPurpose> 
</Contact> 

的邏輯是:

如果子元素名稱是「PurposeAsPlainText「目的地THEN 集‘O’爲其他

ELSEIF子元素名稱是‘PurposeAsEnum’THEN 源值複製到目標

編輯1:我可能會更清楚,因爲沒有任何解決方案將XML解壓縮,請參閱修訂的源和目標XML。

編輯2:這是我測試的XML。下面的兩個轉換解決方案實際上可以在我的原始xml上工作,但不是我使用.NET 4.0 XslCompiledTransform進行測試的修訂後的xml。或者我應該提出一個新問題?

<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <PatientRecord> 
    <Demographics> 
     <Contact> 
     <ContactPurpose> 
      <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
     </ContactPurpose> 
     <ContactPurpose> 
      <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
     </ContactPurpose> 
     </Contact> 
    </Demographics> 
    </PatientRecord> 
</MyDS> 
+0

如果您在子元素爲「PurposeAsEnum」的情況下給出示例輸入和輸出將會很有幫助。 – LarsH 2012-03-05 20:43:16

+0

請參閱修訂後的源和目標XML。所有解決方案都輸出相同的XML,但忘記了拼合並刪除子元素名稱。這個評論中的xml解決方案與我上面希望的輸出不一樣。 Call user610064 2012-03-06 13:49:39

+0

@ user610064:感謝您的編輯。您可能已經注意到,我的答案完全使用您在最新編輯中提供的XML文檔,並生成完全想要的結果。 – 2012-03-06 14:31:38

回答

1

這可以在一個簡單的和短期的方式來完成(沒有明確的條件語句)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:x="cds_dt" exclude-result-prefixes="x"> 
<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="ContactPurpose/x:PurposeAsPlainText/text()">0</xsl:template> 

<xsl:template match="ContactPurpose/*"><xsl:apply-templates/></xsl:template> 
</xsl:stylesheet> 

當施加到下面的XML文檔(擴展到encorporate感興趣這兩種情況下):

<Contact> 
    <ContactPurpose> 
     <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
    </ContactPurpose> 
    <ContactPurpose> 
     <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
    </ContactPurpose> 
</Contact> 

產生想要的,正確的結果

<Contact> 
    <ContactPurpose>0</ContactPurpose> 
    <ContactPurpose>Call</ContactPurpose> 
</Contact> 

說明

重寫identity rule和適當使用的模板/匹配模式。

更新:該任擇議定書已經修改了他的XML文檔,這是現在在默認命名空間:

<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <PatientRecord> 
     <Demographics> 
      <Contact> 
       <ContactPurpose> 
        <PurposeAsPlainText xmlns="cds_dt">Call</PurposeAsPlainText> 
       </ContactPurpose> 
       <ContactPurpose> 
        <PurposeAsEnum xmlns="cds_dt">Call</PurposeAsEnum> 
       </ContactPurpose> 
      </Contact> 
     </Demographics> 
    </PatientRecord> 
</MyDS> 

因此,這裏是產生想要的結果略微修改後的轉換:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="cds_dt" xmlns:c="cds" exclude-result-prefixes="c x"> 
    <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="c:ContactPurpose/x:PurposeAsPlainText/text()">0</xsl:template> 

    <xsl:template match="c:ContactPurpose/*"><xsl:apply-templates/></xsl:template> 
</xsl:stylesheet> 

將此轉換應用於新XML文檔(最接近的上面)時,新的想要的正確結果是produc編號

<MyDS xmlns="cds" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <PatientRecord> 
     <Demographics> 
     <Contact> 
      <ContactPurpose>0</ContactPurpose> 
      <ContactPurpose>Call</ContactPurpose> 
     </Contact> 
     </Demographics> 
    </PatientRecord> 
</MyDS> 
+0

是不是應用轉換,因爲我有兩個XSD文件,但只引用XSLT中的'sub'XSD? (見上面的評論)。或者是C#XslCompiled轉換一個錯誤的類/ XSL解析器? – user610064 2012-03-07 18:20:09

+0

@ user610064:我在發佈之前總是測試我的代碼。使用任何兼容的XSLT 1.0處理器(包括.NET XslCompiledTransform)對所提供的XML文件應用轉換,並獲得所需的結果。很可能你有一個不同的XML文檔,或者有更改的轉換,或兩者兼而有之。 – 2012-03-07 19:13:43

+0

請參閱編輯的問題以及隨附的新評論re:命名空間。我完全按照您發佈的內容複製了您的XSL,但沒有逐字或使用其他名稱空間「cds」取得成功。奇怪... – user610064 2012-03-08 12:52:14

1
<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cds="cds_dt" exclude-result-prefixes="cds"> 
<!-- identity transform - just copy things that don't have a better rule --> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

<!- a rule for what needs changing --> 
<xsl:template match="ContactPurpose[cds:PurposeAsPlainText] "> 
    <ContactPurpose>O</ContactPurpose> 
</xsl:template> 
</xsl:stylesheet> 
+0

這不會產生想要的結果。 – 2012-03-06 14:33:04

+0

當我第一次看到這個答案時,我認爲這是錯誤的,但後來我得出結論,它產生的結果與原始的,模糊的問題是一致的。我想我會把它留給OP來決定它是否與他真正想要的輸出相匹配。 – LarsH 2012-03-08 20:39:00

1

更新:修改了答案,以適應變化的XML源文檔。

的描述不是很清楚,但這裏是我認爲你正在試圖做的:

<xsl:stylesheet version="1.0" xmlns:cds_dt="cds_dt" xmlns:cds="cds" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

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

<xsl:template match="cds:ContactPurpose"> 
    <xsl:copy> 
     <xsl:choose> 
     <!-- when there is a child element PurposeAsPlainText 
      in the cds_dt namespace: --> 
     <xsl:when test="cds_dt:PurposeAsPlainText">0</xsl:when> 
     <!-- I'm guessing that PurposeAsEnum is also supposed to be 
      in the cds_dt namespace. --> 
     <xsl:otherwise> 
      <xsl:value-of select="cds_dt:PurposeAsEnum" /> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

您的解決方案可以在免費的在線工具上運行(但不適用於.NET 4.0 XslCompiledTransform)。您的解決方案不適用於使用修訂後的XML的免費在線工具。我使用:xslt.online-toolz.com/tools/xslt-transformation.php – user610064 2012-03-08 13:13:02

+0

更正您的解決方案在原始XML片段中的工作。謝謝。 – user610064 2012-03-08 13:49:55

+0

@ user610064:我想你不應該因爲不知道你最初發布的代碼片段與你正在使用的實際XML文檔不兼容。代碼片段中的元素實際上是*不同於實際文檔中的元素,因爲它們屬於不同的名稱空間。爲避免將來出現混淆,您需要(a)瞭解XML名稱空間,或(b)在尋求幫助時傳達所有可能相關的詳細信息,以避免忽略此時發生的關鍵細節。 – LarsH 2012-03-08 16:25:06