简体   繁体   English

使用 SAX 解析 XML 并根据值仅获取一个元素

[英]Parse XML using SAX and get only one element based on value

Hello I'm trying to parse an xml file using SAX and filter it based on an element value and save the result in another file.您好,我正在尝试使用 SAX 解析 xml 文件并根据元素值对其进行过滤,并将结果保存在另一个文件中。

the XML file example: XML 文件示例:

<ruleset>
    <rule>
        <condition>
            <case1>String testing</case1>
            <allow>true</allow>
        </condition>
    </rule>
    <rule>
        <condition>
            <case2>String test</case2>
            <allow>false</allow>
        </condition>
    </rule>
</ruleset>

I want the result file to be as follows我希望结果文件如下

<ruleset>
    <rule>
        <condition>
            <case2>String test</case2>
            <allow>false</allow>
        </condition>
    </rule>
</ruleset>

Since the tag has the value "false", So mainly I want to filter the loop element based on the element's value由于标签的值为“false”,所以我主要想根据元素的值过滤循环元素

The code till now helps me filter the all the elements based on the parent element but not on the element.到目前为止的代码帮助我过滤基于父元素而不是元素的所有元素。

final String splitElement = "Rule";


        XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {

            private boolean skip;

            public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes atts)
                    throws SAXException {

                if (qName.equals(splitElement)) {

                    super.startElement(uri, localName, qName, atts);
                    skip = false;
                    
                } else {
                    if (!skip) {
                        super.startElement(uri, localName, qName, atts);
                    }
                }
            }
            
            
            public void endElement(String uri, String localName, String qName) throws SAXException {
                if (!skip) {
                    super.endElement(uri, localName, qName);
                }
            }

            public void characters(char[] ch, int start, int length) throws SAXException {
                if (!skip) {
                    super.characters(ch, start, length);
                }
            }

        };

        Source src = new SAXSource(xr, new InputSource(
                "SourceFilePath"));
        StreamResult res = new StreamResult(new File(
                "DestinantionFilePath"));
        TransformerFactory.newInstance().newTransformer().transform(src, res);

Is it possible to do that using a SAX parser and only keep the "rules" that have an as false ?是否可以使用 SAX 解析器来做到这一点,并且只保留具有 as false 的“规则”?

Not easy because it requires lookahead - you can't decide what do with a rule start tag until you see the allow value some time later.这并不容易,因为它需要先行 - 在一段时间后看到allow值之前,您无法决定如何处理rule开始标记。 The easiest way would be start building a DOM(or DOM-like) tree for each rule, and when you hit the rule end tag, decide whether to keep it or discard it.最简单的方法是开始为每个规则构建一个 DOM(或 DOM 类)树,当您点击rule结束标记时,决定是保留它还是丢弃它。

If you want a streaming solution to this problem using XSLT 3.0, it's如果您想要使用 XSLT 3.0 解决此问题的流式解决方案,它是

<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="rule">
  <xsl:sequence select="copy-of(.)[condition/allow='true']"/>
</xsl:template>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM