📄 fullsyntaxbuilder.java
字号:
// 4.10. QNames String name = element.getTextContent(); int ci = name.indexOf(':'); if (ci != -1) { String prefix = name.substring(0, ci); element.setTextContent(name.substring(ci + 1)); ns = element.lookupNamespaceURI(prefix); element.setAttribute("ns", (ns == null) ? "" : ns); } // 4.16. Constraints if (isDescendantOfFirstChildOfAttribute(element) && "".equals(element.getAttribute("ns")) && "xmlns".equals(element.getTextContent())) throw new GrammarException("name cannot be xmlns"); } else if ("nsName".equals(elementName)) { // 4.16. Constraints if (isDescendantOfFirstChildOfAttribute(element) && "http://www.w3.org/2000/xmlns" .equals(element.getAttribute("ns"))) throw new GrammarException("nsName cannot be XMLNS URI"); } } } break; case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: // 4.2 Whitespace String parentName = parent.getLocalName(); if ("name".equals(parentName)) node.setNodeValue(node.getNodeValue().trim()); if (!"param".equals(parentName) && !"value".equals(parentName) && isWhitespace(node.getNodeValue())) parent.removeChild(node); break; case Node.DOCUMENT_NODE: break; default: parent.removeChild(node); } // Transform children Node ctx = node.getFirstChild(); while (ctx != null) { Node next = ctx.getNextSibling(); transform(ctx); ctx = next; } } /** * Transforms the schema to place all defines under the top-level grammar * element and replace all other grammar elements by their start child. */ private void transformGrammar(Node grammar, Node node) throws GrammarException { if (node.getNodeType() == Node.ELEMENT_NODE) { String elementName = node.getLocalName(); if ("grammar".equals(elementName)) { handleRefs(grammar, node, node); Node start = null; Node ctx = node.getFirstChild(); while (ctx != null) { Node next = ctx.getNextSibling(); String childName = ctx.getLocalName(); if ("define".equals(childName)) grammar.appendChild(ctx); else if ("start".equals(childName)) start = ctx; ctx = next; } if (start == null) throw new GrammarException("no start element for grammar"); Node p = getFirstChildElement(start); Node parent = node.getParentNode(); parent.insertBefore(p, node); parent.removeChild(node); node = p; } Node ctx = node.getFirstChild(); while (ctx != null) { Node next = ctx.getNextSibling(); transformGrammar(grammar, ctx); ctx = next; } } } /** * Checks that all references in the specified grammar match a define in * the grammar. */ private void handleRefs(Node grammar1, Node grammar2, Node node) throws GrammarException { if (node.getNodeType() == Node.ELEMENT_NODE) { String elementName = node.getLocalName(); if ("ref".equals(elementName) || "parentRef".equals(elementName)) { Node grammar = grammar2; if ("parentRef".equals(elementName)) grammar = grammar1; String name = ((Element) node).getAttribute("name"); if (name != null) throw new GrammarException("no name attribute on " + elementName); Node define = null; for (Node ctx = grammar.getFirstChild(); define == null && ctx != null; ctx = ctx.getNextSibling()) { if ("define".equals(ctx.getLocalName())) { String dname = ((Element) ctx).getAttribute("name"); if (name.equals(dname)) define = ctx; } } if (define == null) throw new GrammarException("no define for '" + name + "'"); name = ((Element) define).getAttribute("new-name"); if (name == null) { name = createRefName(); ((Element) define).setAttribute("new-name", name); } if ("parentRef".equals(elementName)) { Document doc = node.getOwnerDocument(); Node ref = doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "ref"); Node ctx = node.getFirstChild(); while (ctx != null) { Node next = ctx.getNextSibling(); ref.appendChild(ctx); ctx = next; } Node parent = node.getParentNode(); parent.insertBefore(ref, node); parent.removeChild(node); node = ref; } ((Element) node).setAttribute("name", name); } else if ("grammar".equals(elementName)) { grammar1 = grammar2; grammar2 = node; } Node ctx = node.getFirstChild(); while (ctx != null) { Node next = ctx.getNextSibling(); handleRefs(grammar1, grammar2, ctx); ctx = next; } } } private String createRefName() { return "ref" + Integer.toString(refCount++); } private void transform2(Node node) throws GrammarException { Node parent = node.getParentNode(); if (node.getNodeType() == Node.ELEMENT_NODE) { String elementName = node.getLocalName(); // 4.20. notAllowed element if ("notAllowed".equals(elementName)) { String parentName = parent.getLocalName(); if ("attribute".equals(parentName) || "list".equals(parentName) || "group".equals(parentName) || "interleave".equals(parentName) || "oneOrMore".equals(parentName)) { Node pp = parent.getParentNode(); pp.insertBefore(node, parent); pp.removeChild(parent); transform2(node); // apply recursively return; } else if ("choice".equals(parentName)) { Node p1 = getFirstChildElement(parent); Node p2 = getNextSiblingElement(p1); if (p1 == null || p2 == null) throw new GrammarException("choice does not have two " + "children"); String p1Name = p1.getLocalName(); String p2Name = p2.getLocalName(); Node pp = parent.getParentNode(); if ("notAllowed".equals(p1Name) && "notAllowed".equals(p2Name)) { pp.insertBefore(p1, parent); pp.removeChild(parent); transform2(p1); //apply recursively return; } else if ("notAllowed".equals(p1Name)) { pp.insertBefore(p2, parent); pp.removeChild(parent); transform2(p2); return; } else { pp.insertBefore(p1, parent); pp.removeChild(parent); transform2(p1); return; } } else if ("except".equals(parentName)) { Node pp = parent.getParentNode(); pp.removeChild(parent); return; } } // 4.21. empty element else if ("empty".equals(elementName)) { String parentName = parent.getLocalName(); if ("group".equals(parentName) || "interleave".equals(parentName)) { Node p1 = getFirstChildElement(parent); Node p2 = getNextSiblingElement(p1); if (p1 == null || p2 == null) throw new GrammarException(parentName + " does not have " + "two children"); String p1Name = p1.getLocalName(); String p2Name = p2.getLocalName(); Node pp = parent.getParentNode(); if ("empty".equals(p1Name) && "empty".equals(p2Name)) { pp.insertBefore(p1, parent); pp.removeChild(parent); transform2(p1); return; } else if ("empty".equals(p1Name)) { pp.insertBefore(p2, parent); pp.removeChild(parent); transform2(p2); return; } else { pp.insertBefore(p1, parent); pp.removeChild(parent); transform2(p1); return; } } else if ("choice".equals(parentName)) { Node p1 = getFirstChildElement(parent); Node p2 = getNextSiblingElement(p1); if (p1 == null || p2 == null) throw new GrammarException(parentName + " does not have " + "two children"); String p1Name = p1.getLocalName(); String p2Name = p2.getLocalName(); Node pp = parent.getParentNode(); if ("empty".equals(p1Name) && "empty".equals(p2Name)) { pp.insertBefore(p1, parent); pp.removeChild(parent); transform2(p1); return; } } else if ("oneOrMore".equals(parentName)) { Node pp = parent.getParentNode(); pp.insertBefore(node, parent); pp.removeChild(parent); transform2(node); return; } } Node ctx = node.getFirstChild(); while (ctx != null) { Node next = ctx.getNextSibling(); transform2(ctx); ctx = next; } } } private static boolean isWhitespace(String text) { int len = text.length(); for (int i = 0; i < len; i++) { char c = text.charAt(i); if (c != ' ' && c != '\t' && c != '\n' && c != '\r') return false; } return true; } private static String escapeURL(String url) { try { return URLEncoder.encode(url, "UTF-8"); } catch (UnsupportedEncodingException e) { RuntimeException e2 = new RuntimeException("UTF-8 is unsupported"); e2.initCause(e); throw e2; } } /** * Resolve a URL to an element, as described in section 4.5. */ private static Element resolve(String url) throws IOException { try { URL u = new URL(url); InputStream in = u.openStream(); DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setNamespaceAware(true); f.setCoalescing(true); f.setExpandEntityReferences(true); f.setIgnoringComments(true); f.setIgnoringElementContentWhitespace(true); DocumentBuilder b = f.newDocumentBuilder(); Document doc = b.parse(in, url); in.close(); String fragment = u.getRef(); if (fragment != null) return doc.getElementById(fragment); return doc.getDocumentElement(); } catch (SAXException e) { IOException e2 = new IOException("error parsing included element"); e2.initCause(e); throw e2; } catch (ParserConfigurationException e) { IOException e2 = new IOException("error parsing included element"); e2.initCause(e); throw e2; } } /** * Returns the "components" of an element, as described in section 4.7. */ private List getComponents(Node node) { List ret = new LinkedList(); for (Node ctx = node.getFirstChild(); ctx != null; ctx = ctx.getNextSibling()) { if (ctx.getNodeType() != Node.ELEMENT_NODE) continue; String ns = ctx.getNamespaceURI(); if (ns != null && !ns.equals(XMLConstants.RELAXNG_NS_URI)) continue; String name = ctx.getLocalName(); if ("div".equals(name)) ret.addAll(getComponents(ctx)); else if (VOCABULARY.containsKey(name)) ret.add(ctx); } return ret; } private static void transformToOneChildElement(Node node, String name) { if (node.getChildNodes().getLength() < 2) return; Document doc = node.getOwnerDocument(); Element child = doc.createElementNS(XMLConstants.RELAXNG_NS_URI, name); Node ctx = getFirstChildElement(node); while (ctx != null) { Node next = getNextSiblingElement(ctx); child.appendChild(ctx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -