0

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文本,并且一些未选择的换行符。)

4

3 回答 3

0

您快到了。您的第一个模板“使用”整个文档,如果您只需要TradeMark标签,只需将其应用于感兴趣的标签。

<xsl:template match="Transaction">
    <xsl:apply-templates select=".//TradeMark"/>
</xsl:template>
于 2013-04-11T02:53:27.737 回答
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 和带有 libxml/20708 和 libxslt/10126 的 xsltproc 产生以下输出:

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,但它确实在那里工作。

于 2013-04-11T04:00:20.453 回答
-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 内置模板完全一样——将模板应用于其所有子元素。

于 2013-04-11T02:59:43.360 回答