elemnumber.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,968 行 · 第 1/5 页
JAVA
1,968 行
case DTM.ATTRIBUTE_NODE : // countMatchPattern = m_stylesheet.createMatchPattern("@"+contextNode.getNodeName(), this); countMatchPattern = new XPath("@" + dtm.getNodeName(contextNode), this, this, XPath.MATCH, support.getErrorListener()); break; case DTM.CDATA_SECTION_NODE : case DTM.TEXT_NODE : // countMatchPattern = m_stylesheet.createMatchPattern("text()", this); countMatchPattern = new XPath("text()", this, this, XPath.MATCH, support.getErrorListener()); break; case DTM.COMMENT_NODE : // countMatchPattern = m_stylesheet.createMatchPattern("comment()", this); countMatchPattern = new XPath("comment()", this, this, XPath.MATCH, support.getErrorListener()); break; case DTM.DOCUMENT_NODE : // countMatchPattern = m_stylesheet.createMatchPattern("/", this); countMatchPattern = new XPath("/", this, this, XPath.MATCH, support.getErrorListener()); break; case DTM.PROCESSING_INSTRUCTION_NODE : // countMatchPattern = m_stylesheet.createMatchPattern("pi("+contextNode.getNodeName()+")", this); countMatchPattern = new XPath("pi(" + dtm.getNodeName(contextNode) + ")", this, this, XPath.MATCH, support.getErrorListener()); break; default : countMatchPattern = null; } } return countMatchPattern; } /** * Given an XML source node, get the count according to the * parameters set up by the xsl:number attributes. * @param transformer non-null reference to the the current transform-time state. * @param sourceNode The source node being counted. * * @return The count of nodes * * @throws TransformerException */ String getCountString(TransformerImpl transformer, int sourceNode) throws TransformerException { long[] list = null; XPathContext xctxt = transformer.getXPathContext(); CountersTable ctable = transformer.getCountersTable(); if (null != m_valueExpr) { XObject countObj = m_valueExpr.execute(xctxt, sourceNode, this); long count = (long)java.lang.Math.floor(countObj.num()+ 0.5); list = new long[1]; list[0] = count; } else { if (Constants.NUMBERLEVEL_ANY == m_level) { list = new long[1]; list[0] = ctable.countNode(xctxt, this, sourceNode); } else { NodeVector ancestors = getMatchingAncestors(xctxt, sourceNode, Constants.NUMBERLEVEL_SINGLE == m_level); int lastIndex = ancestors.size() - 1; if (lastIndex >= 0) { list = new long[lastIndex + 1]; for (int i = lastIndex; i >= 0; i--) { int target = ancestors.elementAt(i); list[lastIndex - i] = ctable.countNode(xctxt, this, target); } } } } return (null != list) ? formatNumberList(transformer, list, sourceNode) : ""; } /** * Get the previous node to be counted. * * @param xctxt The XPath runtime state for this. * @param pos The current node * * @return the previous node to be counted. * * @throws TransformerException */ public int getPreviousNode(XPathContext xctxt, int pos) throws TransformerException { XPath countMatchPattern = getCountMatchPattern(xctxt, pos); DTM dtm = xctxt.getDTM(pos); if (Constants.NUMBERLEVEL_ANY == m_level) { XPath fromMatchPattern = m_fromMatchPattern; // Do a backwards document-order walk 'till a node is found that matches // the 'from' pattern, or a node is found that matches the 'count' pattern, // or the top of the tree is found. while (DTM.NULL != pos) { // Get the previous sibling, if there is no previous sibling, // then count the parent, but if there is a previous sibling, // dive down to the lowest right-hand (last) child of that sibling. int next = dtm.getPreviousSibling(pos); if (DTM.NULL == next) { next = dtm.getParent(pos); if ((DTM.NULL != next) && ((((null != fromMatchPattern) && (fromMatchPattern.getMatchScore( xctxt, next) != XPath.MATCH_SCORE_NONE))) || (dtm.getNodeType(next) == DTM.DOCUMENT_NODE))) { pos = DTM.NULL; // return null from function. break; // from while loop } } else { // dive down to the lowest right child. int child = next; while (DTM.NULL != child) { child = dtm.getLastChild(next); if (DTM.NULL != child) next = child; } } pos = next; if ((DTM.NULL != pos) && ((null == countMatchPattern) || (countMatchPattern.getMatchScore(xctxt, pos) != XPath.MATCH_SCORE_NONE))) { break; } } } else // NUMBERLEVEL_MULTI or NUMBERLEVEL_SINGLE { while (DTM.NULL != pos) { pos = dtm.getPreviousSibling(pos); if ((DTM.NULL != pos) && ((null == countMatchPattern) || (countMatchPattern.getMatchScore(xctxt, pos) != XPath.MATCH_SCORE_NONE))) { break; } } } return pos; } /** * Get the target node that will be counted.. * * @param xctxt The XPath runtime state for this. * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>. * * @return the target node that will be counted * * @throws TransformerException */ public int getTargetNode(XPathContext xctxt, int sourceNode) throws TransformerException { int target = DTM.NULL; XPath countMatchPattern = getCountMatchPattern(xctxt, sourceNode); if (Constants.NUMBERLEVEL_ANY == m_level) { target = findPrecedingOrAncestorOrSelf(xctxt, m_fromMatchPattern, countMatchPattern, sourceNode, this); } else { target = findAncestor(xctxt, m_fromMatchPattern, countMatchPattern, sourceNode, this); } return target; } /** * Get the ancestors, up to the root, that match the * pattern. * * @param patterns if non-null, count only nodes * that match this pattern, if null count all ancestors. * @param xctxt The XPath runtime state for this. * @param node Count this node and it's ancestors. * @param stopAtFirstFound Flag indicating to stop after the * first node is found (difference between level = single * or multiple) * @return The number of ancestors that match the pattern. * * @throws javax.xml.transform.TransformerException */ NodeVector getMatchingAncestors( XPathContext xctxt, int node, boolean stopAtFirstFound) throws javax.xml.transform.TransformerException { NodeSetDTM ancestors = new NodeSetDTM(xctxt.getDTMManager()); XPath countMatchPattern = getCountMatchPattern(xctxt, node); DTM dtm = xctxt.getDTM(node); while (DTM.NULL != node) { if ((null != m_fromMatchPattern) && (m_fromMatchPattern.getMatchScore(xctxt, node) != XPath.MATCH_SCORE_NONE)) { // The following if statement gives level="single" different // behavior from level="multiple", which seems incorrect according // to the XSLT spec. For now we are leaving this in to replicate // the same behavior in XT, but, for all intents and purposes we // think this is a bug, or there is something about level="single" // that we still don't understand. if (!stopAtFirstFound) break; } if (null == countMatchPattern) System.out.println( "Programmers error! countMatchPattern should never be null!"); if (countMatchPattern.getMatchScore(xctxt, node) != XPath.MATCH_SCORE_NONE) { ancestors.addElement(node); if (stopAtFirstFound) break; } node = dtm.getParent(node); } return ancestors; } // end getMatchingAncestors method /** * Get the locale we should be using. * * @param transformer non-null reference to the the current transform-time state. * @param contextNode The node that "." expresses. * * @return The locale to use. May be specified by "lang" attribute, * but if not, use default locale on the system. * * @throws TransformerException */ Locale getLocale(TransformerImpl transformer, int contextNode) throws TransformerException { Locale locale = null; if (null != m_lang_avt) { XPathContext xctxt = transformer.getXPathContext(); String langValue = m_lang_avt.evaluate(xctxt, contextNode, this); if (null != langValue) { // Not really sure what to do about the country code, so I use the // default from the system. // TODO: fix xml:lang handling. locale = new Locale(langValue.toUpperCase(), ""); //Locale.getDefault().getDisplayCountry()); if (null == locale) { transformer.getMsgMgr().warn(this, null, xctxt.getDTM(contextNode).getNode(contextNode), XSLTErrorResources.WG_LOCALE_NOT_FOUND, new Object[]{ langValue }); //"Warning: Could not find locale for xml:lang="+langValue); locale = Locale.getDefault(); } } } else { locale = Locale.getDefault(); } return locale; } /** * Get the number formatter to be used the format the numbers * * @param transformer non-null reference to the the current transform-time state. * @param contextNode The node that "." expresses. * * ($objectName$) @return The number formatter to be used * * @throws TransformerException */ private DecimalFormat getNumberFormatter( TransformerImpl transformer, int contextNode) throws TransformerException { // Patch from Steven Serocki // Maybe we really want to do the clone in getLocale() and return // a clone of the default Locale?? Locale locale = (Locale)getLocale(transformer, contextNode).clone(); // Helper to format local specific numbers to strings. DecimalFormat formatter = null; //synchronized (locale) //{ // formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale); //} String digitGroupSepValue = (null != m_groupingSeparator_avt) ? m_groupingSeparator_avt.evaluate( transformer.getXPathContext(), contextNode, this) : null; // Validate grouping separator if an AVT was used; otherwise this was // validated statically in XSLTAttributeDef.java. if ((digitGroupSepValue != null) && (!m_groupingSeparator_avt.isSimple()) && (digitGroupSepValue.length() != 1)) { transformer.getMsgMgr().warn( this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE, new Object[]{ Constants.ATTRNAME_NAME, m_groupingSeparator_avt.getName()}); } String nDigitsPerGroupValue = (null != m_groupingSize_avt) ? m_groupingSize_avt.evaluate( transformer.getXPathContext(), contextNode, this) : null; // TODO: Handle digit-group attributes if ((null != digitGroupSepValue) && (null != nDigitsPerGroupValue) && // Ignore if separation value is empty string (digitGroupSepValue.length() > 0)) { try { formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale); formatter.setGroupingSize( Integer.valueOf(nDigitsPerGroupValue).intValue()); DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols(); symbols.setGroupingSeparator(digitGroupSepValue.charAt(0)); formatter.setDecimalFormatSymbols(symbols); formatter.setGroupingUsed(true); } catch (NumberFormatException ex) { formatter.setGroupingUsed(false); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?