2011-12-21 37 views
1

這將是我第一次嘗試編寫一個實際上確實有重要意義的XSLT,這對我的工作有所幫助。我之前寫過xpath xpression,並且與他們相處得很好,只需要用XSLT弄溼我的腳,真正開始做飯。 Anywho,編寫一個XSLT以從XML文件中提取某些屬性

我有一個XML文件,其中有一些與value屬性的節點。我想所有的節點與name屬性在一個文本文件打印出自己的value屬性...

這裏是我迄今爲止...示例XML

<?xml version="1.0"?> 
<dataTemplateSpecification> 
<templates> 
<template> 
    <elements> 
    <element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="207"> 
     <mapping path="//Template/TemplateData/ACOData/PATIENT_ID" /> 
     <validation> 
     <rules> 
      <rule id="r0" test="#element0.value == ''"> 
      <fail> 
       <html> 
       <b>Patient ID is null, value must be present</b> 
       </html> 
      </fail> 
      </rule> 
     </rules> 
     </validation> 
    </element> 
    <element id="element1" name="EncounterId" display="Encounter ID" dataType="String" visable="true" readOnly="false" value="144"> 
     <mapping path="//Template/TemplateData/ACOData/FOCUSED_READMISSIONS_ID" /> 
     <validation> 
     <rules> 
      <rule id="r0" test="#element0.value == ''"> 
      <fail> 
       <html> 
       <b>Patient ID is null, value must be present</b> 
       </html> 
      </fail> 
      </rule> 
     </rules> 
     </validation> 
    </element> 
    </template></template></dataTemplateSpecification> 

這是非常基本的我寫了XSLT ...

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
<xsl:output method="text" indent="yes"/> 

<xsl:template match="//dataTemplateSpecification/templates/template/elements/element[@name=*]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@value"/> 
    </xsl:copy> 
</xsl:template> 

我會繼續在這個開裂,如果你們能在所有幫助我會永遠gratefu湖我當然會爲任何閱讀此內容的人發佈解決方案,如果我自己發現解決方案,也會對此問題產生興趣。謝謝。

回答

2

這可能是執行所請求的處理最簡單的和最短的完整的一次轉變:

<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="element[@name and @value]"> 
    <element> 
     <xsl:value-of select= 
     "concat(@name, ': ', @value)"/> 
    </element> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

當這種變換所提供的XML應用(校正多次進行簡潔(wellformed)) :

<dataTemplateSpecification> 
    <templates> 
     <template> 
      <elements> 
       <element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="207"> 
        <mapping path="//Template/TemplateData/ACOData/PATIENT_ID" /> 
        <validation> 
         <rules> 
          <rule id="r0" test="#element0.value == ''"> 
           <fail> 
            <html> 
             <b>Patient ID is null, value must be present</b> 
            </html> 
           </fail> 
          </rule> 
         </rules> 
        </validation> 
       </element> 
       <element id="element1" name="EncounterId" display="Encounter ID" dataType="String" visable="true" readOnly="false" value="144"> 
        <mapping path="//Template/TemplateData/ACOData/FOCUSED_READMISSIONS_ID" /> 
        <validation> 
         <rules> 
          <rule id="r0" test="#element0.value == ''"> 
           <fail> 
            <html> 
             <b>Patient ID is null, value must be present</b> 
            </html> 
           </fail> 
          </rule> 
         </rules> 
        </validation> 
       </element> 
      </elements> 
     </template> 
    </templates> 
</dataTemplateSpecification> 

有用,正確的結果產生

<element>PatientId: 207</element> 
<element>EncounterId: 144</element> 
1

您的XPath謂詞沒有達到您認爲的效果。 *是所有子元素的選擇器,而不是字符串通配符模式。我假設您更希望這樣的事情(即同時具有namevalue屬性的所有element元素):

//element[@name and @value] 

而且打印出的屬性值,你可能想看看xsl:value-of代替xsl:copy和除非你想實際複製元素。

1

像這樣的東西可能:

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

<xsl:output method="text"/> 

<xsl:variable name='newline'><xsl:text> 
</xsl:text></xsl:variable> 

<xsl:template match="//elements"> 
    <xsl:for-each select="//element[@name]"> 
    <xsl:value-of select="concat(@value,$newline)"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
0

其實這不是壞的。對於第一個XSLT,我不可能要求更簡單。我之前寫的東西幾乎可以工作。但是,在此,我需要寫

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
<xsl:output method="text" indent="yes"/> 

<xsl:template match="//dataTemplateSpecification/templates/template/elements/element"> 
    <xsl:copy> 
     <xsl:value-of select="@name"></xsl:value-of>: <xsl:value-of select="@value"/> 
    </xsl:copy> 
</xsl:template> 

這似乎工作相當出色。

+1

DMainEvent:不是太糟糕的開始。以下是一些觀察結果:1.始終使用''的簡寫形式。寫:''和* not *''。2:模板匹配模式指定*相對* XPath表達式(很少包含多個位置步驟)。在你的情況下,它可能只是:'3.你可以使用一個XPath表達式(因此一個單一的')來指定多個比一個字符串:只需使用'concat()'函數。 – 2011-12-21 20:49:40