假设没有可用的XSD/Schema文件,分析XML文件中的混合内容

假设没有可用的XSD/Schema文件,分析XML文件中的混合内容,xml,perl,mixed-content,Xml,Perl,Mixed Content,一个简单的问题,但我似乎在任何地方都找不到答案。。。perl(或者命令行工具)中是否存在检查给定XML文件是否包含混合内容的方法 我只需要一些东西,告诉我,如果混合内容是目前没有。尽管如果发现混合内容,任何细节都将是额外的。如果存在任何文件,那么在不将其完全加载到内存中的情况下处理该文件也会更好,因为我需要分析的文件是100兆字节,在某些情况下甚至是几兆字节。如果什么都不存在,那么我将开始考虑自己写一些东西 所有这些都假设XSD/Schema文件对于给定的XML文件不可用。XPath查询布尔(/

一个简单的问题,但我似乎在任何地方都找不到答案。。。perl(或者命令行工具)中是否存在检查给定XML文件是否包含混合内容的方法

我只需要一些东西,告诉我,如果混合内容是目前没有。尽管如果发现混合内容,任何细节都将是额外的。如果存在任何文件,那么在不将其完全加载到内存中的情况下处理该文件也会更好,因为我需要分析的文件是100兆字节,在某些情况下甚至是几兆字节。如果什么都不存在,那么我将开始考虑自己写一些东西


所有这些都假设XSD/Schema文件对于给定的XML文件不可用。

XPath查询
布尔(/*[text()[normalize-space()]和*])
如果存在同时包含元素和非空白文本子元素的元素,则返回true

对于流式算法,您需要一个堆栈;在堆栈中的每个级别,您都需要跟踪是否在该级别遇到了非空白文本子级和/或元素子级。使用类似SAX的API实现并不太困难,尽管我不知道从Perl开始

对于XSLT 3.0流媒体,我认为可以使用xsl:iterate:

<xsl:mode streamable="yes"/>
<xsl:template match="*">
  <xsl:iterate select="node()">
    <xsl:param name="found-element" select="false()"/>
    <xsl:param name="found-text" select="false()"/>
    <xsl:on-completion>
      <xsl:if test="$found-element and $found-text">
        <out>Found mixed content!!</out>
      </xsl:if>
    </xsl:on-completion>
    <xsl:apply-templates select="."/>
    <xsl:next-iteration>
      <xsl:with-param name="found-element" select="$found-element or self::*"/>
      <xsl:with-param name="found-text" select="$found-text or self::text()[normalize-space()]"/>
    </xsl:next-iteration>
  <xsl:iterate>
</xsl:template>

发现混合内容!!

这方面还有很大的改进空间;当前,如果存在大量混合内容,它将向您提供大量消息。

XPath查询
布尔(//*[text()[normalize-space()]和*])
如果存在同时包含元素和非空白文本子元素的元素,则返回true

对于流式算法,您需要一个堆栈;在堆栈中的每个级别,您都需要跟踪是否在该级别遇到了非空白文本子级和/或元素子级。使用类似SAX的API实现并不太困难,尽管我不知道从Perl开始

对于XSLT 3.0流媒体,我认为可以使用xsl:iterate:

<xsl:mode streamable="yes"/>
<xsl:template match="*">
  <xsl:iterate select="node()">
    <xsl:param name="found-element" select="false()"/>
    <xsl:param name="found-text" select="false()"/>
    <xsl:on-completion>
      <xsl:if test="$found-element and $found-text">
        <out>Found mixed content!!</out>
      </xsl:if>
    </xsl:on-completion>
    <xsl:apply-templates select="."/>
    <xsl:next-iteration>
      <xsl:with-param name="found-element" select="$found-element or self::*"/>
      <xsl:with-param name="found-text" select="$found-text or self::text()[normalize-space()]"/>
    </xsl:next-iteration>
  <xsl:iterate>
</xsl:template>

发现混合内容!!
这方面还有很大的改进空间;目前,如果有很多混合内容,它会给你很多信息