2017-07-28 196 views
0

每天早上將多個xml文件轉儲到每個文件夾中,每個文件包含一個記錄。這些文件中的每一個都有近300個節點,但我只需要發送約20條信息。所以出於顯而易見的原因,我想只提取所需的數據而不是刪除不需要的數據。我一直試圖用xslt來做到這一點,但不能完全正確。我嘗試了很多不同的模板,我不會在這裏發佈它們。相反,我只是舉一個例子的源xml和我需要的輸出xml。使用XSLT僅從XML解析需要的信息

Source.xml:

<?xml version="1.0"?> 
<NewDataSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Report> 
     <Overview> 
      <Agency>Agengcy1</Agency> 
      <AgencyNumber>2346</AgencyNumber> 
      <ReportDate>2017-07-24</ReportDate> 
     </Overview> 
     <Summary> 
      <ReportNumber>17-092447</ReportNumber> 
      <Boxes>2</Boxes> 
      <Crates>1</Crates> 
     </Summary> 
     <Unit> 
      <Order> 
       <LastName>SMITH</LastName> 
       <FirstName>JOHN</FirstName> 
       <Address>123 MAIN</Address> 
       <Floor>2</Floor> 
       <State>IL</State> 
       <City>CHICAGO</City> 
       <Zip>60007</Zip> 
      </Order> 
     </Unit> 
     <Unit> 
      <Order> 
       <LastName>SMITH</LastName> 
       <FirstName>JANE</FirstName> 
       <Address>123 MAIN</Address> 
       <Floor>7</Floor> 
       <State>IL</State> 
       <City>CHICAGO</City> 
       <Zip>60007</Zip> 
      </Order> 
     </Unit> 
    </Report> 
</NewDataSet> 

的Output.xml:

<?xml version="1.0"?> 
<Report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Agency>Agengcy1</Agency> 
    <ReportDate>2017-07-24</ReportDate> 
    <ReportNumber>17-092447</ReportNumber> 
     <Unit> 
      <LastName>SMITH</LastName> 
      <FirstName>JOHN</FirstName> 
      <Floor>2</Floor> 
     </Unit> 
     <Unit> 
      <LastName>SMITH</LastName> 
      <FirstName>JANE</FirstName> 
      <Floor>7</Floor> 
     </Unit> 
</Report> 

我應該我XSLT模樣,以獲得與Output.xml,包括縮進?預先感謝您

編輯 我試過以下,但它留下輸出空間。此外,我停下來,一旦我意識到我將不得不添加近300個xsl:template match =「」語句。 此:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<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="AgencyNumber"/> 
<xsl:template match="Boxes"/> 
<xsl:template match="Crates"/> 
<xsl:template match="Address"/> 
<xsl:template match="State"/> 
<xsl:template match="City"/> 
<xsl:template match="Zip"/> 

</xsl:stylesheet> 

獲取我:

<Report> 
    <Overview> 
     <Agency>Agency1</Agency> 

     <ReportDate>2017-07-24</ReportDate> 
    </Overview> 
    <Summary> 
     <ReportNumber>17-092447</ReportNumber> 


    <Unit> 
     <Order> 
      <LastName>SMITH</LastName> 
      <FirstName>JOHN</FirstName> 

      <Floor>2</Floor> 



     </Order> 
    </Unit> 
</Report> 

月2日更新 我也用這個:

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

<xsl:output method="xml" indent="yes"/> 

<xsl:template match="/NewDataSet/Report"> 
    <Report> 
    <Agcy><xsl:value-of select="Overview/Agency" /></Agcy> 
    <Date><xsl:value-of select="Overview/ReportDate" /></Date> 
    <RprtNbr><xsl:value-of select="Summary/ReportNumber" /></RprtNbr> 
     <Unit> 
      <Last><xsl:value-of select="Unit/Order/LastName" /></Last> 
      <First><xsl:value-of select="Unit/Order/FirstName" /></First> 
      <Floor><xsl:value-of select="Unit/Order/Floor" /></Floor> 
     </Unit> 
    </Report> 
</xsl:template> 

</xsl:stylesheet> 

但它出來是這樣的:

<?xml version="1.0" encoding="utf-8"?> 
    <Report><Agcy>Agengcy1</Agcy><Date>2017-07-24</Date><RprtNbr>17-092447</RprtNbr><Unit><Last>SMITH</Last><First>JOHN</First><Floor>2</Floor></Unit></Report> 
+0

爲什麼不把它加載到XDocument中,抓取需要的並保存它? – Will

+0

@我是新來的xml遊戲,現在由於各種原因,我正在使用Visual Studio的'XML任務'。什麼是XDocument? – Jfire

+0

「*我一直試圖用xslt來做到這一點,但不能完全正確。*」爲什麼不發佈你的嘗試,以便我們可以修復它,而不必從頭開始爲你編寫代碼。 –

回答

0

而不是刪除你不想要的作品,儘量只得到了件你想:

XSLT 1.0

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

<xsl:template match="Report"> 
    <xsl:copy> 
     <xsl:copy-of select="Overview/Agency | Overview/ReportDate | Summary/ReportNumber"/> 
     <xsl:for-each select="Unit"> 
      <xsl:copy> 
       <xsl:copy-of select="Order/LastName | Order/FirstName | Order/Floor"/> 
      </xsl:copy> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

或者,如果你喜歡:

XSLT 1.0

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

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

<xsl:template match="/NewDataSet"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="Overview"> 
    <xsl:apply-templates select="Agency | ReportDate"/> 
</xsl:template> 

<xsl:template match="Summary"> 
    <xsl:apply-templates select="ReportNumber"/> 
</xsl:template> 

<xsl:template match="Order"> 
    <xsl:apply-templates select="LastName | FirstName | Floor"/> 
</xsl:template> 

</xsl:stylesheet> 
+0

真棒,這工作!所以管道字符是創建額外單元節點的原因嗎?我很欣賞這個例子!我能夠將這些應用到我的真實數據中,並且就像我需要的一樣。現在我可以簡單地使用Visual Studio'Foreach Loop Container'中的任務來遍歷文件夾中的所有文件。 – Jfire

+0

不,管道字符是聯合操作符。創建附加'單元'節點的是第一個樣式表中的'xsl:for-each'指令,以及第二個樣式表中的標識轉換模板。 –