使用下面的XML,如何仅将地址详细信息提取为CSV格式?
我认为我需要一个基于Identity模板的样式表,尽管我发现的示例很简单,并在列表中列出了要排除的元素。有没有一种简单的方法可以排除除Address和AddressLine之外的所有内容?
我正在使用.NET处理XLST转换。到目前为止,我提出的样式表没有返回任何内容。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:strip-space elements="*"/>
<xsl:param name="delim" select="','" />
<xsl:param name="quote" select="'"'" />
<xsl:param name="break" select="'
'" />
<xsl:template match="node()| @*">
<xsl:copy>
<xsl:apply-templates select="node()| @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="AddressLine" priority="9">
<xsl:value-of select="concat($quote, ., $quote, $delim)"/>
</xsl:template>
<xsl:template match="*" priority="0" />
</xsl:stylesheet>
<Sample Version="6" Date="2012-05-11">
<Header>
<CreatedDate>2015-12-02</CreatedDate>
<CreatedTime>10:31:42</CreatedTime>
</Header>
<Message Group="1" Type="1" Protocol="1">
<MessageHeader>
<MessageReferenceNumber>1</MessageReferenceNumber>
</MessageHeader>
<TransactionHeader>
<ReportPeriodStartDate>2002-04-01</ReportPeriodStartDate>
<ReportPeriodEndDate>2015-11-30</ReportPeriodEndDate>
</TransactionHeader>
<Episode>
<Person>
<General>
<Verified Status="02">
<Identifier>001</Identifier>
<PersonName>
<Name>
<FirstName>Foo</FirstName>
<Surname>Bar</Surname>
</Name>
</PersonName>
<Address>
<AddressLine></AddressLine>
<AddressLine>Street</AddressLine>
<AddressLine>Town</AddressLine>
<AddressLine>City</AddressLine>
</Address>
</Verified>
</General>
</Person>
<Session>
<Input>
<StartDate>2015-10-31</StartDate>
<StartTime>17:15:00</StartTime>
</Input>
<Output>
<StatusCode>8</StatusCode>
<LocationCode>9</LocationCode>
</Output>
</Session>
</Episode>
<MessageTrailer>
<MessageReferenceNumber>1</MessageReferenceNumber>
</MessageTrailer>
</Message>
<Message Group="1" Type="1" Protocol="1">
<MessageHeader>
<MessageReferenceNumber>2</MessageReferenceNumber>
</MessageHeader>
<TransactionHeader>
<ReportPeriodStartDate>2002-04-01</ReportPeriodStartDate>
<ReportPeriodEndDate>2015-11-30</ReportPeriodEndDate>
</TransactionHeader>
<Episode>
<Person>
<General>
<Verified Status="02">
<Identifier>002</Identifier>
<PersonName>
<Name>
<FirstName>Foo</FirstName>
<Surname>Bar</Surname>
</Name>
</PersonName>
<Address>
<AddressLine></AddressLine>
<AddressLine>Street</AddressLine>
<AddressLine>Town</AddressLine>
<AddressLine>City</AddressLine>
</Address>
</Verified>
</General>
</Person>
<Session>
<Input>
<StartDate>2015-10-31</StartDate>
<StartTime>17:15:00</StartTime>
</Input>
<Output>
<StatusCode>8</StatusCode>
<LocationCode>9</LocationCode>
</Output>
</Session>
</Episode>
<MessageTrailer>
<MessageReferenceNumber>2</MessageReferenceNumber>
</MessageTrailer>
</Message>
<Trailer>
<RecordCount>2</RecordCount>
</Trailer>
</Sample>
如果你想创建纯文本,我认为身份转换模板没有意义,你只需要一个根节点的模板
<xsl:template match="/">
<xsl:apply-templates select="//Address"/>
</xsl:template>
然后,您可以编写模板,为Address
或其子级AddressLine
执行您想要或需要输出的操作。
作为替代方案,您可以利用现有的默认模板来递归处理子节点,只需要确保覆盖text()
节点的模板,否则所有元素的所有文本都将被输出。
所以要么试试
<xsl:template match="/">
<xsl:apply-templates select="//Address"/>
</xsl:template>
<xsl:template match="AddressLine">
<xsl:value-of select="concat($quote, ., $quote, $delim)"/>
</xsl:template>
或者仅仅是像这样的方法
<xsl:template match="*[not(self::Address)]/text()"/>
<xsl:template match="AddressLine">
<xsl:value-of select="concat($quote, ., $quote, $delim)"/>
</xsl:template>
在这两种情况下,我都不确定您想要的生产线的确切结果,因此可能需要进行一些调整来插入或添加换行符。
一个简单的方法是"重新定义"内置模板规则,只复制选定的模板规则-在本例中为Address
和子节点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*|@*">
<xsl:apply-templates select="*" />
</xsl:template>
<xsl:template match="Address">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
导致
<?xml version="1.0"?>
<Address>
<AddressLine/>
<AddressLine>Street</AddressLine>
<AddressLine>Town</AddressLine>
<AddressLine>City</AddressLine>
</Address>
<Address>
<AddressLine/>
<AddressLine>Street</AddressLine>
<AddressLine>Town</AddressLine>
<AddressLine>City</AddressLine>
</Address>
无需添加明确的模板优先级,只需使用一个匹配AddressLine
的模板和另一个模板,即可在默认情况下防止输出所有文本节点。
样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:strip-space elements="*"/>
<xsl:param name="delim" select="','" />
<xsl:param name="quote" select="'"'" />
<xsl:param name="break" select="'
'" />
<xsl:template match="AddressLine">
<xsl:value-of select="concat($quote, ., $quote, $delim)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
文本输出
"","Street","Town","City","","Street","Town","City",
如果您希望输出有所不同,请解释应该更改的内容。