本文介绍了读取转义的引号作为xml的转义引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



代码为:

  public class MyTest {
public static void main(String [] args){
Document doc = XMLUtils.fileToDom(MyTest.xml); //加载xml数据到DOM
元素rootElement = doc.getDocumentElement();
NodeList nodes = rootElement.getChildNodes();
Node child1 = nodes.item(1);
Node child2 = nodes.item(3);
String str1 = child1.getTextContent();
String str2 = child2.getTextContent();
if(str1!= null){
System.out.println(str1.equals(str2));
}
System.out.println();
System.out.println(str1);
System.out.println(str2);
}

}



MyTest.xml

 < tests> 
< test name =1> ff1& quot< / test>
< test name =2> ff1< / test>
< / tests>

结果:

  true 

ff1
ff1

所需结果:

  false 

ff1& quot;
ff1

所以我需要区分这两种情况:报价是否被转义而不是。



请帮助。



提前谢谢。



PS XMLUtils的代码#fileToDom(String filePath),一个来自XMLUtils类的代码片段:

  static {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
dFactory.setNamespaceAware(false);
dFactory.setValidating(false);
try {
docNonValidatingBuilder = dFactory.newDocumentBuilder();
} catch(ParserConfigurationException e){
}
}

public static DocumentBuilder getNonValidatingBuilder(){
return docNonValidatingBuilder;
}

public static Document fileToDom(String filePath){

Document doc = getNonValidatingBuilder()。newDocument();
文件f = new File(filePath);
if(!f.exists())
return doc;

try {
Transformer transformer = TransformerFactory.newInstance()。newTransformer();
DOMResult result = new DOMResult(doc);
StreamSource source = new StreamSource(f);
transformer.transform(source,result);
} catch(Exception e){
return doc;
}

return doc;

}


解决方案

看看apache xerces的源代码,并提出我的解决方案(但它是猴子补丁)。
我写了简单的类

 打包a; 
import java.io.IOException;
import org.apache.xerces.impl.XMLDocumentScannerImpl;
import org.apache.xerces.parsers.NonValidatingConfiguration;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLComponent;

public class MyConfig extends NonValidatingConfiguration {

private MyScanner myScanner;

@Override
@SuppressWarnings(unchecked)
protected void configurePipeline(){
if(myScanner == null){
myScanner = new MyScanner();
addComponent((XMLComponent)myScanner);
}
super.fProperties.put(DOCUMENT_SCANNER,myScanner);
super.fScanner = myScanner;
super.fScanner.setDocumentHandler(this.fDocumentHandler);
super.fLastComponent = fScanner;
}

私有静态类MyScanner扩展XMLDocumentScannerImpl {

@Override
protected void scanEntityReference()throws IOException,XNIException {
// name
String name = super.fEntityScanner.scanName();
if(name == null){
reportFatalError(NameRequiredInReference,null);
return;
}

super.fDocumentHandler.characters(new XMLString((&+ name +;)
.toCharArray(),0,name.length() + 2),null);

// end
if(!super.fEntityScanner.skipChar(';')){
reportFatalError(SemicolonRequiredInReference,
new Object [] {name });
}
fMarkupDepth--;
}
}

}

在开始解析前仅添加下一行到您的主要方法

  System.setProperty(
org.apache.xerces .xni.parser.XMLParserConfiguration,
a.MyConfig);

您将有预期的结果:

  false 

ff1& quot;
ff1


I load xml file into DOM model and analyze it.

The code for that is:

public class MyTest {
public static void main(String[] args) {        
    Document doc = XMLUtils.fileToDom("MyTest.xml");//Loads xml data to DOM
    Element rootElement = doc.getDocumentElement();
    NodeList nodes = rootElement.getChildNodes();
    Node child1 = nodes.item(1);
    Node child2 = nodes.item(3);
    String str1 = child1.getTextContent();
    String str2 = child2.getTextContent();      
    if(str1 != null){
        System.out.println(str1.equals(str2));
    }
    System.out.println();
    System.out.println(str1);
    System.out.println(str2);
}   

}

MyTest.xml

<tests>
   <test name="1">ff1 &quot;</test>
   <test name="2">ff1 "</test>
</tests>

Result:

true

ff1 "
ff1 "

Desired result:

false

ff1 &quot;
ff1 "

So I need to distinguish these two cases: when the quote is escaped and is not.

Please help.

Thank you in advance.

P.S. The code for XMLUtils#fileToDom(String filePath), a snippet from XMLUtils class:

static {
    DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
    dFactory.setNamespaceAware(false);
    dFactory.setValidating(false);
    try {
        docNonValidatingBuilder = dFactory.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
    }
}

public static DocumentBuilder getNonValidatingBuilder() {
    return docNonValidatingBuilder;
}

public static Document fileToDom(String filePath) {

    Document doc = getNonValidatingBuilder().newDocument();
    File f = new File(filePath);
    if(!f.exists())
        return doc;

    try {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        DOMResult result = new DOMResult(doc);
        StreamSource source = new StreamSource(f);
        transformer.transform(source, result);
    } catch (Exception e) {
        return doc;
    }

    return doc;

}
解决方案

I've take a look on source code of apache xerces and propose my solution (but it is monkey patch).I've wrote simple class

package a;
import java.io.IOException;
import org.apache.xerces.impl.XMLDocumentScannerImpl;
import org.apache.xerces.parsers.NonValidatingConfiguration;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLComponent;

public class MyConfig extends NonValidatingConfiguration {

    private MyScanner myScanner;

    @Override
    @SuppressWarnings("unchecked")
    protected void configurePipeline() {
        if (myScanner == null) {
            myScanner = new MyScanner();
            addComponent((XMLComponent) myScanner);
        }
        super.fProperties.put(DOCUMENT_SCANNER, myScanner);
        super.fScanner = myScanner;
        super.fScanner.setDocumentHandler(this.fDocumentHandler);
        super.fLastComponent = fScanner;
    }

    private static class MyScanner extends XMLDocumentScannerImpl {

        @Override
        protected void scanEntityReference() throws IOException, XNIException {
            // name
            String name = super.fEntityScanner.scanName();
            if (name == null) {
                reportFatalError("NameRequiredInReference", null);
                return;
            }

            super.fDocumentHandler.characters(new XMLString(("&" + name + ";")
                .toCharArray(), 0, name.length() + 2), null);

            // end
            if (!super.fEntityScanner.skipChar(';')) {
                reportFatalError("SemicolonRequiredInReference",
                        new Object[] { name });
            }
            fMarkupDepth--;
        }
    }

}

You need to add only next line to your main method before start parsing

System.setProperty(
            "org.apache.xerces.xni.parser.XMLParserConfiguration",
            "a.MyConfig");

And you will have expected result:

false

ff1 &quot;
ff1 "

这篇关于读取转义的引号作为xml的转义引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 23:50