【问题标题】:Read escaped quote as escaped quote from xml将转义引号读取为来自 xml 的转义引号
【发布时间】:2009-12-30 11:49:58
【问题描述】:

我将 xml 文件加载到 DOM 模型中并对其进行分析。

代码如下:

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>

结果:

true

ff1 "
ff1 "

想要的结果:

false

ff1 &quot;
ff1 "

所以我需要区分这两种情况:当引号被转义和不是。

请帮忙。

提前谢谢你。

附: XMLUtils#fileToDom(String filePath) 的代码,来自 XMLUtils 类的 sn-p:

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;

}

【问题讨论】:

  • 如果你不介意,你为什么需要这个? " 的编码只是为了适合您的 XML 文档,不属于您的原始数据(应该是 &amp;amp;quot;

标签: java xml escaping


【解决方案1】:

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

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--;
        }
    }

}

在开始解析之前,您只需在 main 方法中添加下一行

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

你会得到预期的结果:

false

ff1 &quot;
ff1 "

【讨论】:

    【解决方案2】:

    看起来您可以获取 TEXT_NODE 子节点并使用 getNodeValue(假设它不为 NULL):

    public static String getRawContent(Node n) {
      if (n == null) {
          return null;
      }
    
      Node n1 = getChild(n, Node.TEXT_NODE);
    
      if (n1 == null) {
          return null;
      }
    
      return n1.getNodeValue();
    }
    

    从: http://www.java2s.com/Code/Java/XML/Gettherawtextcontentofanodeornullifthereisnotext.htm

    【讨论】:

    • 不,这不会给你带来任何不同。我不知道作者所说的“原始”是什么意思,但不是这样。
    【解决方案3】:

    没有办法对内部实体执行此操作。 XML 不支持这个概念。内部实体只是将相同的 PSVI 内容写入文本的不同方式,它们没有区别。

    【讨论】:

      猜你喜欢
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2017-01-08
      相关资源
      最近更新 更多