使用以下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>
答案 0 :(得分:1)
如果您想创建纯文本,我认为身份转换模板没有意义,您需要的只是根节点的模板
<xsl:template match="/">
<xsl:apply-templates select="//Address"/>
</xsl:template>
然后你就可以像往常一样编写模板,为Address
或其子AddressLine
做你想要或需要输出的内容。
作为替代方案,您可以利用存在的默认模板来递归处理子节点,只需要确保覆盖text()
节点的节点,否则将输出所有元素的所有文本。 / p>
所以要么尝试
<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>
在这两种情况下,我都不确定在生成的行方面你想要哪个确切的结果,因此可能需要对插入或添加换行符进行一些调整。
答案 1 :(得分:0)
无需添加显式模板优先级,只需使用匹配String strDetails = PropertyLoader.get("details");
String strDataKey1= PropertyLoader.get("datakey1");
String strDataKey2 = PropertyLoader.get("datakey2");
String strDetailsOrg = strDetails;
strDetails = strDetails.replace(strDataKey1, "Programmatically Generated Value 1");
strDetailsOrg = strDetailsOrg.replace(strDataKey2, "Programmatically Generated Value 2");
的模板和其他模板即可默认输出所有文本节点。
<强>样式表强>
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>
如果您希望输出不同,请说明应该更改的内容。
答案 2 :(得分:0)
一种简短的方法是“重新定义”内置模板规则,只复制选定的模板规则 - 在本例中为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>