Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 在转换期间删除没有属性、子元素或文本的元素_Xml_Xslt - Fatal编程技术网

Xml 在转换期间删除没有属性、子元素或文本的元素

Xml 在转换期间删除没有属性、子元素或文本的元素,xml,xslt,Xml,Xslt,XSL很难实现。我的问题的答案让我基本上走上了正确的轨道,但有一些小事情我最初忽略了。以下是我的最新尝试: XSL: <!-- When a file is transformed using this stylesheet the output will be formatted as follows: 1.) Elements named "info" will be removed 2.) Attributes named "file_line_

XSL很难实现。我的问题的答案让我基本上走上了正确的轨道,但有一些小事情我最初忽略了。以下是我的最新尝试:

XSL:

<!--
    When a file is transformed using this stylesheet the output will be
    formatted as follows:

    1.)  Elements named "info" will be removed
    2.)  Attributes named "file_line_nr" or "file_name" will be removed
    3.)  Comments will be removed
    4.)  Processing instructions will be removed
    5.)  XML declaration will be removed
    6.)  Extra whitespace will be removed
    7.)  Empty attributes will be removed
    8.)  Elements void of both attributes and child elements will be removed
    9.)  All elements will be sorted by name recursively
    10.) All attributes will be sorted by name
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <!--
        Elements/attributes to remove.  Note that comments are not elements or
        attributes.  Since there is no template to match comments they are
        automatically ignored.
    -->
    <xsl:template match="@*[normalize-space()='']|info|@file_line_nr|@file_name"/>

    <!-- Match any attribute -->
    <xsl:template match="@*">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
        </xsl:copy>
    </xsl:template>

    <!-- Match any element -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="@*">
                <xsl:sort select="name()"/>
            </xsl:apply-templates>
            <xsl:apply-templates>
                <xsl:sort select="name()"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!-- XML declaration should be removed -->
<foo b="b" a="a" c="c">
    <?some-app inst="some instruction"?><!-- Processing instructions should be removed -->
    <qwer><!-- Keep elements like this because it has child elements -->
        <zxcv c="c" b="b"/><!-- Keep elements like this because it has attributes -->
        <id>some text</id><!-- Keep elements like this because it has text -->
        <info i="i"/><!-- Elements named "info" are to be removed -->
        <rewq file_line_nr="42" file_name="somefile.txt"/><!-- Attributes named "file_line_nr" and "file_name" are to be removed which will leave this element empty, so it should be removed too -->
        <vcxz c="c" b="b"/>
    </qwer>
    <baz e="e" d="d"/>
    <bar>
        <fdsa g="g" f="f"/>
        <asdf g="g" f="f"/>
    </bar>
</foo>

我想我已经满足了我的每一个要求,除了8号。我可以成功地创建一个样式表,删除没有子元素的元素,或者删除没有属性的元素,但这不是我想要的。我只想删除没有属性、子元素或文本的元素

输入XML:

<!--
    When a file is transformed using this stylesheet the output will be
    formatted as follows:

    1.)  Elements named "info" will be removed
    2.)  Attributes named "file_line_nr" or "file_name" will be removed
    3.)  Comments will be removed
    4.)  Processing instructions will be removed
    5.)  XML declaration will be removed
    6.)  Extra whitespace will be removed
    7.)  Empty attributes will be removed
    8.)  Elements void of both attributes and child elements will be removed
    9.)  All elements will be sorted by name recursively
    10.) All attributes will be sorted by name
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <!--
        Elements/attributes to remove.  Note that comments are not elements or
        attributes.  Since there is no template to match comments they are
        automatically ignored.
    -->
    <xsl:template match="@*[normalize-space()='']|info|@file_line_nr|@file_name"/>

    <!-- Match any attribute -->
    <xsl:template match="@*">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
        </xsl:copy>
    </xsl:template>

    <!-- Match any element -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="@*">
                <xsl:sort select="name()"/>
            </xsl:apply-templates>
            <xsl:apply-templates>
                <xsl:sort select="name()"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!-- XML declaration should be removed -->
<foo b="b" a="a" c="c">
    <?some-app inst="some instruction"?><!-- Processing instructions should be removed -->
    <qwer><!-- Keep elements like this because it has child elements -->
        <zxcv c="c" b="b"/><!-- Keep elements like this because it has attributes -->
        <id>some text</id><!-- Keep elements like this because it has text -->
        <info i="i"/><!-- Elements named "info" are to be removed -->
        <rewq file_line_nr="42" file_name="somefile.txt"/><!-- Attributes named "file_line_nr" and "file_name" are to be removed which will leave this element empty, so it should be removed too -->
        <vcxz c="c" b="b"/>
    </qwer>
    <baz e="e" d="d"/>
    <bar>
        <fdsa g="g" f="f"/>
        <asdf g="g" f="f"/>
    </bar>
</foo>

一些文本
所需的输出XML:(无注释、无空格/缩进、元素和属性已排序)


一些文本

这应该可以完成以下工作:

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

  <!--
        Elements/attributes to remove.  Note that comments are not elements or
        attributes.  Since there is no template to match comments they are
        automatically ignored.
    -->
  <xsl:template match="@*[normalize-space()='']|info|@file_line_nr|@file_name"/>

  <!-- Match any attribute -->
  <xsl:template match="@*">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Match any element -->
  <xsl:template match="*">
    <xsl:variable name="elementFragment">
      <xsl:copy>
        <xsl:apply-templates select="@*">
          <xsl:sort select="name()"/>
        </xsl:apply-templates>
        <xsl:apply-templates>
          <xsl:sort select="name()"/>
        </xsl:apply-templates>
      </xsl:copy>
    </xsl:variable>
    <xsl:variable name="element" select="msxsl:node-set($elementFragment)/*"/>
    <xsl:if test="$element/@* or $element/* or normalize-space($element)">
      <xsl:copy-of select="$element"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

其思想是预处理元素,将结果放入变量中,然后执行“元素” 对变量没有属性、子元素或文本测试


变量是一个XML片段,需要使用扩展函数将其转换为节点集-my XSLT使用Microsoft one
msxsl:node set
-其他处理器具有等效的函数。

最简单的方法是使用一个规则来抑制对所有元素的处理:

<xsl:template match="*"/>

我是否应该将您建议的XPath放在自己的模板中,优先级低于当前的空模板,以便在确定某个元素确实为“空”之前,先删除我不想要的空属性和特定元素(如
info
),所以优先权技巧不起作用。太棒了。我认为这正是我想要的,但它有一个不幸的副作用,那就是比我所拥有的时间要长得多(转换一个15MB的文件需要25秒,而我所拥有的只有5秒)。我将继续测试,以确保我没有错过任何角落的案件。我实现了
节点集
,如回答中所述。
match="*[@*] | *[*]"