加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用XSLT排除XML空节点

发布时间:2020-12-16 22:55:37 所属栏目:百科 来源:网络整理
导读:我有一些非常简单的 XML.我正在重新创建一些 XML并在最终的XML文件中添加一些样板文本,以便在完成后导入InDesign. 问题在于:并非所有XML字段都在每条记录中使用.因此,当XSLT添加样板文本时,它甚至会出现在不包含XML元素的记录中. 我尝试使用选择当否则要查
我有一些非常简单的 XML.我正在重新创建一些 XML并在最终的XML文件中添加一些样板文本,以便在完成后导入InDesign.

问题在于:并非所有XML字段都在每条记录中使用.因此,当XSLT添加样板文本时,它甚至会出现在不包含XML元素的记录中.

我尝试使用选择>>当>>否则要查找元素,然后使用元素if,否则忽略样板,如果元素不在记录中,则插入NOTHING.

以下是一些示例XML数据:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <story>
        <CL>
            <CityDescription>City One</CityDescription>
            <BK>
                <CompanyName>Corporate Name</CompanyName>
                <address>123 Main St</address>
                <HoldingCo>Company Name</HoldingCo>
                <TotalAssets>128,319,000</TotalAssets>
                <TotalLiabilities>117,059,000</TotalLiabilities>
                <TotalDeposits>89,847,000</TotalDeposits>
                <EquityCapital>11,260,000</EquityCapital>
            </BK>
            <BK>
                <CompanyName>Smaller Company</CompanyName>
                <address>123 Central St</address>
            </BK>
        </CL>
        <CL>
            <CityDescription>City Two</CityDescription>
            <BK>
                <CompanyName>Corporate Name Three</CompanyName>
                <address>123 High St</address>
                <HoldingCo>Company Name</HoldingCo>
                <TotalAssets>128,000</EquityCapital>
            </BK>
            <BK>
                <CompanyName>Smaller Company Four</CompanyName>
                <address>123 Jones St</address>
            </BK>
        </CL>
    </story>
</root>

这是我试图使用的XSLT,但它添加了“Holding Co:”和“Total Assets:”甚至包含不包含元素的记录:

<?xml version="1.0" encoding="UTF-8"?><!-- DWXMLSource="Testing.xml" -->
<!DOCTYPE xsl:stylesheet  [
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="XML" />
<xsl:template match="/">

<root>
    <story>
        <xsl:for-each select="root/story/CL">
            <CityDescription><xsl:value-of select="CityDescription"/></CityDescription><xsl:text>
            </xsl:text>
            <xsl:for-each select="BK">
                <CompanyName><xsl:value-of select="CompanyName"/></CompanyName><xsl:text>
                </xsl:text>
                <address><xsl:value-of select="address"/></address><xsl:text>
                </xsl:text>
                <HoldingCo><xsl:text>Holding Co: </xsl:text><xsl:value-of select="HoldingCo"/></HoldingCo><xsl:text>
                </xsl:text>
                <TotalAssets><xsl:text>Total Assets: </xsl:text><xsl:value-of select="TotalAssets"/></TotalAssets><xsl:text>
                </xsl:text>
                <TotalLiabilities><xsl:text>Total Liabilities: </xsl:text><xsl:value-of select="TotalLiabilities"/></TotalLiabilities><xsl:text>
                </xsl:text>
                <TotalDeposits><xsl:text>Total Deposits: </xsl:text><xsl:value-of select="TotalDeposits"/></TotalDeposits><xsl:text>
                </xsl:text>
                <EquityCapital><xsl:text>Total Assets: </xsl:text><xsl:value-of select="EquityCapital"/></EquityCapital><xsl:text>
                </xsl:text>
            </xsl:for-each>
        </xsl:for-each>
    </story>
</root>
</xsl:template>
</xsl:stylesheet>

我尝试使用Choose>>当>>否则基本上忽略了元素,等等它们没有出现在数据中,但我的输出只显示“否则”内容.

有什么建议?

解决方法

Here's the problem: not all XML fields are being used in every record. So,when the XSLT adds the boilerplate text it appears even in the records that don't include the XML elements.

这就是模板的用途 – 在XSLT中不使用模板就像不使用OO编程语言中的类.

这个简单的转换(请注意,没有使用过单个条件指令):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vNL" select="'&#xA;'"/>
    <xsl:template match="/">
        <root>
            <story>
              <xsl:apply-templates select="root/story/CL"/>
            </story>
        </root>
    </xsl:template>

    <xsl:template match="CL">
      <xsl:apply-templates select="CityDescription"/>
      <xsl:apply-templates select="BK"/>
    </xsl:template>

    <xsl:template match="CityDescription | CompanyName | address">
        <xsl:element name="{name()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="BK">
      <xsl:value-of select="$vNL"/>
      <xsl:apply-templates select="CompanyName"/>
      <xsl:apply-templates select="address"/>
      <xsl:apply-templates select="HoldingCo"/>
      <xsl:apply-templates select="TotalAssets"/>
      <xsl:apply-templates select="TotalLiabilities"/>
      <xsl:apply-templates select="TotalDeposits"/>
      <xsl:apply-templates select="EquityCapital"/>
    </xsl:template>

    <xsl:template match="HoldingCo">
        <HoldingCo>
            <xsl:text>Holding Co: </xsl:text>
            <xsl:value-of select="."/>
        </HoldingCo>
    </xsl:template>

    <xsl:template match="TotalAssets">
        <TotalAssets>
            <xsl:text>Total Assets: </xsl:text>
            <xsl:value-of select="."/>
        </TotalAssets>
    </xsl:template>

    <xsl:template match="TotalLiabilities">
        <TotalLiabilities>
            <xsl:text>Total Liabilities: </xsl:text>
            <xsl:value-of select="."/>
        </TotalLiabilities>
    </xsl:template>

    <xsl:template match="TotalDeposits">
        <TotalDeposits>
            <xsl:text>Total Deposits: </xsl:text>
            <xsl:value-of select="."/>
        </TotalDeposits>
    </xsl:template>

    <xsl:template match="EquityCapital">
        <EquityCapital>
            <xsl:text>Total Assets: </xsl:text>
            <xsl:value-of select="."/>
        </EquityCapital>
    </xsl:template>

    <xsl:template match="text()"/>
</xsl:stylesheet>

当应用于提供的XML文档时:

<root>
    <story>
        <CL>
            <CityDescription>City One</CityDescription>
            <BK>
                <CompanyName>Corporate Name</CompanyName>
                <address>123 Main St</address>
                <HoldingCo>Company Name</HoldingCo>
                <TotalAssets>128,000</EquityCapital>
            </BK>
            <BK>
                <CompanyName>Smaller Company Four</CompanyName>
                <address>123 Jones St</address>
            </BK>
        </CL>
    </story>
</root>

产生想要的,正确的结果:

<root>
   <story>
      <CityDescription>City One</CityDescription>

      <CompanyName>Corporate Name</CompanyName>
      <address>123 Main St</address>
      <HoldingCo>Holding Co: Company Name</HoldingCo>
      <TotalAssets>Total Assets: 128,000</TotalAssets>
      <TotalLiabilities>Total Liabilities: 117,000</TotalLiabilities>
      <TotalDeposits>Total Deposits: 89,000</TotalDeposits>
      <EquityCapital>Total Assets: 11,000</EquityCapital>

      <CompanyName>Smaller Company</CompanyName>
      <address>123 Central St</address>
      <CityDescription>City Two</CityDescription>

      <CompanyName>Corporate Name Three</CompanyName>
      <address>123 High St</address>
      <HoldingCo>Holding Co: Company Name</HoldingCo>
      <TotalAssets>Total Assets: 128,000</EquityCapital>

      <CompanyName>Smaller Company Four</CompanyName>
      <address>123 Jones St</address>
   </story>
</root>

由于BK的子元素按文档顺序处理,匹配模板可简化为:

<xsl:template match="BK">
    <xsl:value-of select="$vNL"/>
    <xsl:apply-templates/>
</xsl:template>

这对于匹配CL的模板也是有效的 – 它可以替换为:

<xsl:template match="CL">
    <xsl:apply-templates/>
</xsl:template>

最后,可以完全删除此模板,因为它完全复制了与任何元素匹配的XSLT内置模板.

因此,这些重构后的转换是:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vNL" select="'&#xA;'"/>
    <xsl:template match="/">
        <root>
            <story>
              <xsl:apply-templates select="root/story/CL"/>
            </story>
        </root>
    </xsl:template>

    <xsl:template match="CityDescription | CompanyName | address">
        <xsl:element name="{name()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="BK">
        <xsl:value-of select="$vNL"/>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="HoldingCo">
        <HoldingCo>
            <xsl:text>Holding Co: </xsl:text>
            <xsl:value-of select="."/>
        </HoldingCo>
    </xsl:template>

    <xsl:template match="TotalAssets">
        <TotalAssets>
            <xsl:text>Total Assets: </xsl:text>
            <xsl:value-of select="."/>
        </TotalAssets>
    </xsl:template>

    <xsl:template match="TotalLiabilities">
        <TotalLiabilities>
            <xsl:text>Total Liabilities: </xsl:text>
            <xsl:value-of select="."/>
        </TotalLiabilities>
    </xsl:template>

    <xsl:template match="TotalDeposits">
        <TotalDeposits>
            <xsl:text>Total Deposits: </xsl:text>
            <xsl:value-of select="."/>
        </TotalDeposits>
    </xsl:template>

    <xsl:template match="EquityCapital">
        <EquityCapital>
            <xsl:text>Total Assets: </xsl:text>
            <xsl:value-of select="."/>
        </EquityCapital>
    </xsl:template>

    <xsl:template match="text()"/>
</xsl:stylesheet>

说明:

说明:

<xsl:apply-templates select="someChildName"/>

如果存在someChildName子节点,则仅应用模板(执行处理).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读