将XSLT文本提取限制为特定字段

时间:2013-04-11 02:34:42

标签: xml xslt text extraction

XSLT还是一个新手;我正在尝试使用XSLT(1.0)从XML文件中提取某些字段,但只提取某些字段。这是实际XML文档的简化形式:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Transaction>
  <TradeMarkTransactionBody>
    <TransactionContentDetails>
      <TransactionCode>National Trademark Information</TransactionCode>
      <TransactionData>
        <TradeMarkDetails>
          <TradeMark>
            <RegistrationOfficeCode>US</RegistrationOfficeCode>
            <ApplicationNumber>74631225</ApplicationNumber>
            <ApplicationDate>1995-02-07-05:00</ApplicationDate>
            <RegistrationNumber>2178784</RegistrationNumber>
            <RegistrationDate>1998-08-04-04:00</RegistrationDate>
            <FilingPlace>US</FilingPlace>
            <MarkCurrentStatusDate>2008-08-11-04:00</MarkCurrentStatusDate>
            <WordMarkSpecification>
              <MarkVerbalElementText>JAVA </MarkVerbalElementText>
            </WordMarkSpecification>
          </TradeMark>
        </TradeMarkDetails>
      </TransactionData>
    </TransactionContentDetails>
  </TradeMarkTransactionBody>
</Transaction>

这是我的XSLT尝试:

<?xml version="1.0" encoding="utf-8"?>
<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:template match="Transaction">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="TradeMark">
MarkCurrentStatusDate,"<xsl:value-of select="MarkCurrentStatusDate"/>"
ApplicationNumber,"<xsl:value-of select="ApplicationNumber"/>"
ApplicationDate,"<xsl:value-of select="ApplicationDate"/>"
RegistrationNumber,"<xsl:value-of select="RegistrationNumber"/>"
RegistrationDate,"<xsl:value-of select="RegistrationDate"/>"
ExpirationDate,"<xsl:value-of select="ExpirationDate"/>"
<xsl:apply-templates select="WordMarkSpecification"/>
</xsl:template>

<xsl:template match="WordMarkSpecification">
MarkVerbalElementText,"<xsl:value-of select="normalize-space(MarkVerbalElementText)"/>"
</xsl:template>
</xsl:stylesheet>

哪个近乎有效,导致:

National Trademark Information
MarkCurrentStatusDate,"2008-08-11-04:00"
ApplicationNumber,"74631225"
ApplicationDate,"1995-02-07-05:00"
RegistrationNumber,"2178784"
RegistrationDate,"1998-08-04-04:00"
ExpirationDate,""

MarkVerbalElementText,"JAVA"

我的问题:1)如何避免在输出中拾取不需要的数据,例如TransactionCode(“National Trademark Information”); 2)如何避免ExpirationDateMarkVerbalElementText之间的空白? (我已经确认它不是XSLT文件中的空行;将它们删除没有效果。)

(我怀疑这两个问题可能只有一个答案;我在某种程度上保留了未选择的MarkVerbalElementText文本,一些未选择的换行符。)

3 个答案:

答案 0 :(得分:0)

你快到了。您的第一个模板“消耗”整个文档,如果您只想要TradeMark标记,则只需应用于感兴趣的标记。

<xsl:template match="Transaction">
    <xsl:apply-templates select=".//TradeMark"/>
</xsl:template>

答案 1 :(得分:0)

这是另一种(有点复杂的)拉动方法:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:util="urn:util">

    <xsl:output
        method="text" 
        encoding="utf-8"/>

    <xsl:strip-space elements="*"/>

    <xsl:variable name="fields" select="document('')/*/util:fields"/>
    <util:fields>
        <field>MarkCurrentStatusDate</field>
        <field>ApplicationNumber</field>
        <field>ApplicationDate</field>
        <field>RegistrationNumber</field>
        <field>RegistrationDate</field>
        <field>ExpirationDate</field>
        <field>MarkVerbalElementText</field>
    </util:fields>

    <xsl:template match="/">
        <xsl:variable name="xml" select="."/>
        <xsl:for-each select="$fields/field">
            <xsl:variable name="f" select="."/>
            <xsl:value-of select="$f"/>
            <xsl:text>="</xsl:text>
            <xsl:value-of select="normalize-space($xml//TradeMark//*[local-name() = $f])"/>
            <xsl:text>"&#x000A;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

使用Saxon 6.5.5,Saxon-EE 9.4.0.3和xsltproc以及libxml / 20708和libxslt / 10126得到以下输出:

MarkCurrentStatusDate="2008-08-11-04:00"
ApplicationNumber="74631225"
ApplicationDate="1995-02-07-05:00"
RegistrationNumber="2178784"
RegistrationDate="1998-08-04-04:00"
ExpirationDate=""
MarkVerbalElementText="JAVA"

我对它提供的样本XML不太自信,但它确实在那里工作。

答案 2 :(得分:-1)

以下是所提供转换的略微修正和简化(删除了一个不必要的模板) - 现在生成想要的正确结果

<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:template match="TradeMark">
    MarkCurrentStatusDate,"<xsl:value-of select="MarkCurrentStatusDate"/>"
    ApplicationNumber,"<xsl:value-of select="ApplicationNumber"/>"
    ApplicationDate,"<xsl:value-of select="ApplicationDate"/>"
    RegistrationNumber,"<xsl:value-of select="RegistrationNumber"/>"
    RegistrationDate,"<xsl:value-of select="RegistrationDate"/>"
    ExpirationDate,"<xsl:value-of select="ExpirationDate"/><xsl:text>"</xsl:text>
    <xsl:apply-templates select="WordMarkSpecification"/>
 </xsl:template>

 <xsl:template match="WordMarkSpecification">
    MarkVerbalElementText,"<xsl:value-of select="normalize-space(MarkVerbalElementText)"/>"
 </xsl:template>

 <xsl:template match="TransactionCode"/>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<Transaction>
    <TradeMarkTransactionBody>
        <TransactionContentDetails>
            <TransactionCode>National Trademark Information</TransactionCode>
            <TransactionData>
                <TradeMarkDetails>
                    <TradeMark>
                        <RegistrationOfficeCode>US</RegistrationOfficeCode>
                        <ApplicationNumber>74631225</ApplicationNumber>
                        <ApplicationDate>1995-02-07-05:00</ApplicationDate>
                        <RegistrationNumber>2178784</RegistrationNumber>
                        <RegistrationDate>1998-08-04-04:00</RegistrationDate>
                        <FilingPlace>US</FilingPlace>
                        <MarkCurrentStatusDate>2008-08-11-04:00</MarkCurrentStatusDate>
                        <WordMarkSpecification>
                            <MarkVerbalElementText>JAVA </MarkVerbalElementText>
                        </WordMarkSpecification>
                    </TradeMark>
                </TradeMarkDetails>
            </TransactionData>
        </TransactionContentDetails>
    </TradeMarkTransactionBody>
</Transaction>

产生了想要的正确结果:

MarkCurrentStatusDate,"2008-08-11-04:00"
ApplicationNumber,"74631225"
ApplicationDate,"1995-02-07-05:00"
RegistrationNumber,"2178784"
RegistrationDate,"1998-08-04-04:00"
ExpirationDate,""
MarkVerbalElementText,"JAVA"

<强>解释

  1. 空身模板:

    <xsl:template match="TransactionCode"/>

    用于覆盖与元素匹配的XSLT内置模板,该模板生成匹配元素的所有文本节点后代的串联。

  2. 该行末尾的<xsl:text>"</xsl:text>可防止将后续的换行符解释为所需输出的一部分,从而消除了观察到的空行。

  3. 模板匹配Transaction已被删除,因为它的行为与匹配元素的XSLT内置模板完全相同 - 将模板应用于其所有子项。