使用XSLT仅从XML解析需要的信息

问题描述:

每天早上将多个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来做到这一点,但不能完全正确。*”为什么不发布你的尝试,以便我们可以修复它,而不必从头开始为你编写代码。 –

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

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'指令,以及第二个样式表中的标识转换模板。 –